Cleanup: Geometry Nodes: General topology map creation in Shortest Edge Paths

Use general util to build mesh topology map instead of array of vectors.
This util can be optimized in future by better multithreading and new
algorithms with better CPU catch heuristics. For now this will provide
better usage of memory without a lot of small allocations.

Pull Request: https://projects.blender.org/blender/blender/pulls/114683
This commit is contained in:
Iliya Katueshenock
2023-11-10 15:20:56 +01:00
committed by Hans Goudey
parent 2a24e29241
commit 8618547dfe

View File

@@ -10,6 +10,7 @@
#include "BLI_task.hh"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.hh"
#include "node_geometry_util.hh"
@@ -25,23 +26,8 @@ static void node_declare(NodeDeclarationBuilder &b)
using VertPriority = std::pair<float, int>;
struct EdgeVertMap {
Array<Vector<int>> edges_by_vertex_map;
EdgeVertMap(const Mesh &mesh)
{
const Span<int2> edges = mesh.edges();
edges_by_vertex_map.reinitialize(mesh.totvert);
for (const int edge_i : edges.index_range()) {
const int2 &edge = edges[edge_i];
edges_by_vertex_map[edge[0]].append(edge_i);
edges_by_vertex_map[edge[1]].append(edge_i);
}
}
};
static void shortest_paths(const Mesh &mesh,
EdgeVertMap &maps,
const GroupedSpan<int> vert_to_edge,
const IndexMask end_selection,
const VArray<float> &input_cost,
MutableSpan<int> r_next_index,
@@ -65,8 +51,7 @@ static void shortest_paths(const Mesh &mesh,
continue;
}
visited[vert_i] = true;
const Span<int> incident_edge_indices = maps.edges_by_vertex_map[vert_i];
for (const int edge_i : incident_edge_indices) {
for (const int edge_i : vert_to_edge[vert_i]) {
const int2 &edge = edges[edge_i];
const int neighbor_vert_i = edge[0] + edge[1] - vert_i;
if (visited[neighbor_vert_i]) {
@@ -117,8 +102,12 @@ class ShortestEdgePathsNextVertFieldInput final : public bke::MeshFieldInput {
Array<float> cost(mesh.totvert, FLT_MAX);
if (!end_selection.is_empty()) {
EdgeVertMap maps(mesh);
shortest_paths(mesh, maps, end_selection, input_cost, next_index, cost);
const Span<int2> edges = mesh.edges();
Array<int> vert_to_edge_offset_data;
Array<int> vert_to_edge_indices;
const GroupedSpan<int> vert_to_edge = bke::mesh::build_vert_to_edge_map(
edges, mesh.totvert, vert_to_edge_offset_data, vert_to_edge_indices);
shortest_paths(mesh, vert_to_edge, end_selection, input_cost, next_index, cost);
}
threading::parallel_for(next_index.index_range(), 1024, [&](const IndexRange range) {
for (const int i : range) {
@@ -193,8 +182,12 @@ class ShortestEdgePathsCostFieldInput final : public bke::MeshFieldInput {
Array<float> cost(mesh.totvert, FLT_MAX);
if (!end_selection.is_empty()) {
EdgeVertMap maps(mesh);
shortest_paths(mesh, maps, end_selection, input_cost, next_index, cost);
const Span<int2> edges = mesh.edges();
Array<int> vert_to_edge_offset_data;
Array<int> vert_to_edge_indices;
const GroupedSpan<int> vert_to_edge = bke::mesh::build_vert_to_edge_map(
edges, mesh.totvert, vert_to_edge_offset_data, vert_to_edge_indices);
shortest_paths(mesh, vert_to_edge, end_selection, input_cost, next_index, cost);
}
threading::parallel_for(cost.index_range(), 1024, [&](const IndexRange range) {
for (const int i : range) {