Cleanup: Tweaks to the Mesh Merge by Distance code

- Improve comments
- Rename variables
- Reduce indentation
- Use `const` types
- Use `OffsetIndices` API

Pull Request: https://projects.blender.org/blender/blender/pulls/109919
This commit is contained in:
Germano Cavalcante
2023-07-11 01:59:25 +02:00
committed by Germano Cavalcante
parent 3046b0a19e
commit 1457c0c533

View File

@@ -80,6 +80,8 @@ struct WeldPoly {
};
struct WeldMesh {
/* These vectors indicate the index of elements that will participate in the creation of groups.
* These groups are used in customdata interpolation (`do_mix_data`). */
Vector<int> double_verts;
Vector<int> double_edges;
@@ -359,21 +361,21 @@ static Vector<WeldEdge> weld_edge_ctx_alloc_and_find_collapsed(Span<int2> edges,
int v2 = edges[i][1];
int v_dest_1 = vert_dest_map[v1];
int v_dest_2 = vert_dest_map[v2];
if ((v_dest_1 != OUT_OF_CONTEXT) || (v_dest_2 != OUT_OF_CONTEXT)) {
const int vert_a = (v_dest_1 != OUT_OF_CONTEXT) ? v_dest_1 : v1;
const int vert_b = (v_dest_2 != OUT_OF_CONTEXT) ? v_dest_2 : v2;
if (v_dest_1 == OUT_OF_CONTEXT && v_dest_2 == OUT_OF_CONTEXT) {
r_edge_dest_map[i] = OUT_OF_CONTEXT;
continue;
}
if (vert_a == vert_b) {
edge_collapsed_len++;
r_edge_dest_map[i] = ELEM_COLLAPSED;
}
else {
wedge.append({i, vert_a, vert_b});
r_edge_dest_map[i] = i;
}
const int vert_a = (v_dest_1 == OUT_OF_CONTEXT) ? v1 : v_dest_1;
const int vert_b = (v_dest_2 == OUT_OF_CONTEXT) ? v2 : v_dest_2;
if (vert_a == vert_b) {
r_edge_dest_map[i] = ELEM_COLLAPSED;
edge_collapsed_len++;
}
else {
r_edge_dest_map[i] = OUT_OF_CONTEXT;
wedge.append({i, vert_a, vert_b});
r_edge_dest_map[i] = i;
}
}
@@ -382,13 +384,15 @@ static Vector<WeldEdge> weld_edge_ctx_alloc_and_find_collapsed(Span<int2> edges,
}
/**
* Configure Weld Edges.
* Fills `r_edge_dest_map` indicating the duplicated edges.
*
* \return r_edge_dest_map: Map of indices pointing edges that will be merged.
* \return r_wedge: Weld edges. `flag` and `edge_dest` members will be set here.
* \return r_edge_double_kill_len: Number of edges to be destroyed by merging or collapsing.
* \param weld_edges: Candidate edges for merging (edges that don't collapse and that have at least
* one weld vertex).
*
* \return r_edge_dest_map: Map of indices pointing the source edges to eacth targed.
* \return r_edge_double_kill_len: Number of duplicate edges to be destroyed.
*/
static void weld_edge_find_doubles(Span<WeldEdge> wedge,
static void weld_edge_find_doubles(Span<WeldEdge> weld_edges,
int mvert_num,
MutableSpan<int> r_edge_dest_map,
int *r_edge_double_kill_len)
@@ -396,7 +400,7 @@ static void weld_edge_find_doubles(Span<WeldEdge> wedge,
/* Setup Edge Overlap. */
int edge_double_kill_len = 0;
if (wedge.size() == 0) {
if (weld_edges.size() == 0) {
*r_edge_double_kill_len = edge_double_kill_len;
return;
}
@@ -404,7 +408,7 @@ static void weld_edge_find_doubles(Span<WeldEdge> wedge,
/* Add +1 to allow calculation of the length of the last group. */
Array<int> v_links(mvert_num + 1, 0);
for (const WeldEdge &we : wedge) {
for (const WeldEdge &we : weld_edges) {
BLI_assert(r_edge_dest_map[we.edge_orig] != ELEM_COLLAPSED);
BLI_assert(we.vert_a != we.vert_b);
v_links[we.vert_a]++;
@@ -422,8 +426,8 @@ static void weld_edge_find_doubles(Span<WeldEdge> wedge,
Array<int> link_edge_buffer(link_len);
/* Use a reverse for loop to ensure that indexes are assigned in ascending order. */
for (int i = wedge.size(); i--;) {
const WeldEdge &we = wedge[i];
for (int i = weld_edges.size(); i--;) {
const WeldEdge &we = weld_edges[i];
BLI_assert(r_edge_dest_map[we.edge_orig] != ELEM_COLLAPSED);
int dst_vert_a = we.vert_a;
int dst_vert_b = we.vert_b;
@@ -432,8 +436,8 @@ static void weld_edge_find_doubles(Span<WeldEdge> wedge,
link_edge_buffer[--v_links[dst_vert_b]] = i;
}
for (const int i : wedge.index_range()) {
const WeldEdge &we = wedge[i];
for (const int i : weld_edges.index_range()) {
const WeldEdge &we = weld_edges[i];
BLI_assert(r_edge_dest_map[we.edge_orig] != OUT_OF_CONTEXT);
if (r_edge_dest_map[we.edge_orig] != we.edge_orig) {
/* Already a duplicate. */
@@ -472,7 +476,7 @@ static void weld_edge_find_doubles(Span<WeldEdge> wedge,
}
int e_ctx_b = *edges_ctx_b;
if (e_ctx_a == e_ctx_b) {
const WeldEdge &we_b = wedge[e_ctx_b];
const WeldEdge &we_b = weld_edges[e_ctx_b];
BLI_assert(ELEM(we_b.vert_a, dst_vert_a, dst_vert_b));
BLI_assert(ELEM(we_b.vert_b, dst_vert_a, dst_vert_b));
BLI_assert(we_b.edge_orig != edge_orig);
@@ -1271,8 +1275,7 @@ static void weld_mesh_context_create(const Mesh &mesh,
*
* \param dest_map: Map that defines the source and target elements. The source elements will be
* merged into the target. Each target corresponds to a group.
* \param double_elems: Affected elements in `dest_map` that will compose groups.
* Used for performance only.
* \param double_elems: Source and target elements in `dest_map`. For quick access.
*
* \return r_groups_map: Map that points out the group of elements that an element belongs to.
* \return r_groups_buffer: Buffer containing the indices of all elements that merge.
@@ -1282,7 +1285,7 @@ static void merge_groups_create(Span<int> dest_map,
Span<int> double_elems,
Array<int> &r_groups_map,
Array<int> &r_groups_buffer,
Array<int> &r_groups_offs)
Array<int> &r_groups_offsets)
{
r_groups_map.reinitialize(dest_map.size());
r_groups_map.fill(OUT_OF_CONTEXT);
@@ -1305,31 +1308,28 @@ static void merge_groups_create(Span<int> dest_map,
}
/* Add +1 to allow calculation of the length of the last group. */
r_groups_offs.reinitialize(wgroups_len + 1);
r_groups_offs.fill(0);
r_groups_offsets = Array<int>(wgroups_len + 1, 0);
/* TODO: Check using #array_utils::count_indices instead. At the moment it cannot be used
* because `dest_map` has negative values and `double_elems` (which indicates only the indexes to
* be read) is not used. */
for (const int elem_orig : double_elems) {
const int elem_dest = dest_map[elem_orig];
const int group_index = r_groups_map[elem_dest];
r_groups_offs[group_index]++;
r_groups_offsets[group_index]++;
}
int offs = 0;
for (const int i : IndexRange(wgroups_len)) {
offs += r_groups_offs[i];
r_groups_offs[i] = offs;
}
r_groups_offs[wgroups_len] = offs;
const OffsetIndices offsets = offset_indices::accumulate_counts_to_offsets(r_groups_offsets);
r_groups_buffer.reinitialize(offs);
r_groups_buffer.reinitialize(offsets.total_size());
BLI_assert(r_groups_buffer.size() == double_elems.size());
/* Use a reverse for loop to ensure that indexes are assigned in ascending order. */
/* Use a reverse for loop to ensure that indices are assigned in ascending order. */
for (int i = double_elems.size(); i--;) {
const int elem_orig = double_elems[i];
const int elem_dest = dest_map[elem_orig];
const int group_index = r_groups_map[elem_dest];
r_groups_buffer[--r_groups_offs[group_index]] = elem_orig;
r_groups_buffer[--r_groups_offsets[group_index]] = elem_orig;
}
}
@@ -1428,6 +1428,21 @@ static void customdata_weld(
}
}
/**
* \brief Applies to `CustomData *dest` the values in `CustomData *source`.
*
* This function creates the CustomData of the resulting mesh according to the merge map in
* `dest_map`. The resulting customdata will not have the source elements, so the indexes will be
* modified. To indicate the new indices `r_final_map` is also created.
*
* \param dest_map: Map that defines the source and target elements. The source elements will be
* merged into the target. Each target corresponds to a group.
* \param double_elems: Source and target elements in `dest_map`. For quick access.
* \param do_mix_data: If true the target element will have the custom data interpolated with all
* sources pointing to it.
*
* \return r_final_map: Array indicating the new indices of the elements.
*/
static void merge_customdata_all(const CustomData *source,
CustomData *dest,
Span<int> dest_map,
@@ -1441,9 +1456,9 @@ static void merge_customdata_all(const CustomData *source,
const int source_size = dest_map.size();
MutableSpan<int> groups_map;
Array<int> groups_buffer, groups_offs;
Array<int> groups_buffer, groups_offs_;
if (do_mix_data) {
merge_groups_create(dest_map, double_elems, r_final_map, groups_buffer, groups_offs);
merge_groups_create(dest_map, double_elems, r_final_map, groups_buffer, groups_offs_);
/**
* Be careful when setting values to this array as it uses the same buffer as #r_final_map.
@@ -1454,6 +1469,7 @@ static void merge_customdata_all(const CustomData *source,
else {
r_final_map.reinitialize(source_size);
}
OffsetIndices<int> groups_offs(groups_offs_);
bool finalize_map = false;
int dest_index = 0;
@@ -1474,10 +1490,12 @@ static void merge_customdata_all(const CustomData *source,
}
if (dest_map[i] == i) {
if (do_mix_data) {
const int grp_index = groups_map[i];
const int grp_buffer_offs = groups_offs[grp_index];
const int grp_buffer_len = groups_offs[grp_index + 1] - grp_buffer_offs;
customdata_weld(source, dest, &groups_buffer[grp_buffer_offs], grp_buffer_len, dest_index);
const IndexRange grp_buffer_range = groups_offs[groups_map[i]];
customdata_weld(source,
dest,
&groups_buffer[grp_buffer_range.start()],
grp_buffer_range.size(),
dest_index);
}
else {
CustomData_copy_data(source, dest, i, dest_index, 1);
@@ -1506,7 +1524,7 @@ static void merge_customdata_all(const CustomData *source,
}
if (finalize_map) {
for (int i : r_final_map.index_range()) {
for (const int i : r_final_map.index_range()) {
if (r_final_map[i] < 0) {
r_final_map[i] = r_final_map[-r_final_map[i]];
BLI_assert(r_final_map[i] < dest_size);