Geometry Nodes: Slightly optimize mesh to curve node
Use the offset indices pattern to avoid keeping separate arrays for the offset of a vertex's neighbors and the number of neighbors. This gave a 9% speedup for the conversion, from 42.9 ms to 39.3 ms.
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace blender::geometry {
|
||||
|
||||
bke::CurvesGeometry create_curve_from_vert_indices(
|
||||
BLI_NOINLINE bke::CurvesGeometry create_curve_from_vert_indices(
|
||||
const bke::AttributeAccessor &mesh_attributes,
|
||||
const Span<int> vert_indices,
|
||||
const Span<int> curve_offsets,
|
||||
@@ -80,27 +80,20 @@ struct CurveFromEdgesOutput {
|
||||
IndexRange cyclic_curves;
|
||||
};
|
||||
|
||||
static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
|
||||
const Span<int2> edges)
|
||||
BLI_NOINLINE static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
|
||||
const Span<int2> edges)
|
||||
{
|
||||
Vector<int> vert_indices;
|
||||
vert_indices.reserve(edges.size());
|
||||
Vector<int> curve_offsets;
|
||||
|
||||
/* Compute the number of edges connecting to each vertex. */
|
||||
Array<int> neighbor_count(verts_num, 0);
|
||||
for (const int2 &edge : edges) {
|
||||
neighbor_count[edge[0]]++;
|
||||
neighbor_count[edge[1]]++;
|
||||
}
|
||||
|
||||
/* Compute an offset into the array of neighbor edges based on the counts. */
|
||||
Array<int> neighbor_offsets(verts_num);
|
||||
int start = 0;
|
||||
for (const int i : IndexRange(verts_num)) {
|
||||
neighbor_offsets[i] = start;
|
||||
start += neighbor_count[i];
|
||||
Array<int> neighbor_offsets_data(verts_num + 1, 0);
|
||||
for (const int vert : edges.cast<int>()) {
|
||||
neighbor_offsets_data[vert]++;
|
||||
}
|
||||
offset_indices::accumulate_counts_to_offsets(neighbor_offsets_data);
|
||||
const OffsetIndices<int> neighbor_offsets(neighbor_offsets_data);
|
||||
|
||||
/* Use as an index into the "neighbor group" for each vertex. */
|
||||
Array<int> used_slots(verts_num, 0);
|
||||
@@ -109,8 +102,8 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
|
||||
for (const int i : edges.index_range()) {
|
||||
const int v1 = edges[i][0];
|
||||
const int v2 = edges[i][1];
|
||||
neighbors[neighbor_offsets[v1] + used_slots[v1]] = v2;
|
||||
neighbors[neighbor_offsets[v2] + used_slots[v2]] = v1;
|
||||
neighbors[neighbor_offsets[v1].start() + used_slots[v1]] = v2;
|
||||
neighbors[neighbor_offsets[v2].start() + used_slots[v2]] = v1;
|
||||
used_slots[v1]++;
|
||||
used_slots[v2]++;
|
||||
}
|
||||
@@ -120,7 +113,7 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
|
||||
|
||||
for (const int start_vert : IndexRange(verts_num)) {
|
||||
/* The vertex will be part of a cyclic curve. */
|
||||
if (neighbor_count[start_vert] == 2) {
|
||||
if (neighbor_offsets[start_vert].size() == 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -129,9 +122,9 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const int i : IndexRange(neighbor_count[start_vert])) {
|
||||
for (const int neighbor : neighbors.as_span().slice(neighbor_offsets[start_vert])) {
|
||||
int current_vert = start_vert;
|
||||
int next_vert = neighbors[neighbor_offsets[current_vert] + i];
|
||||
int next_vert = neighbor;
|
||||
|
||||
if (unused_edges[next_vert] == 0) {
|
||||
continue;
|
||||
@@ -150,11 +143,11 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
|
||||
unused_edges[current_vert]--;
|
||||
unused_edges[last_vert]--;
|
||||
|
||||
if (neighbor_count[current_vert] != 2) {
|
||||
if (neighbor_offsets[current_vert].size() != 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
const int offset = neighbor_offsets[current_vert];
|
||||
const int offset = neighbor_offsets[current_vert].start();
|
||||
const int next_a = neighbors[offset];
|
||||
const int next_b = neighbors[offset + 1];
|
||||
next_vert = (last_vert == next_a) ? next_b : next_a;
|
||||
@@ -172,7 +165,7 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
|
||||
}
|
||||
|
||||
int current_vert = start_vert;
|
||||
int next_vert = neighbors[neighbor_offsets[current_vert]];
|
||||
int next_vert = neighbors[neighbor_offsets[current_vert].start()];
|
||||
|
||||
curve_offsets.append(vert_indices.size());
|
||||
vert_indices.append(current_vert);
|
||||
@@ -186,7 +179,7 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
|
||||
unused_edges[current_vert]--;
|
||||
unused_edges[last_vert]--;
|
||||
|
||||
const int offset = neighbor_offsets[current_vert];
|
||||
const int offset = neighbor_offsets[current_vert].start();
|
||||
const int next_a = neighbors[offset];
|
||||
const int next_b = neighbors[offset + 1];
|
||||
next_vert = (last_vert == next_a) ? next_b : next_a;
|
||||
@@ -198,7 +191,7 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num,
|
||||
return {std::move(vert_indices), std::move(curve_offsets), cyclic_curves};
|
||||
}
|
||||
|
||||
static bke::CurvesGeometry edges_to_curves_convert(
|
||||
BLI_NOINLINE static bke::CurvesGeometry edges_to_curves_convert(
|
||||
const Mesh &mesh,
|
||||
const Span<int2> edges,
|
||||
const bke::AnonymousAttributePropagationInfo &propagation_info)
|
||||
|
||||
Reference in New Issue
Block a user