Lagrange
dijkstra.h
1/*
2 * Copyright 2022 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12
13#pragma once
14
15#include <lagrange/Mesh.h>
16#include <lagrange/legacy/inline.h>
17#include <lagrange/utils/assert.h>
18
19#include <array>
20#include <queue>
21#include <vector>
22
23namespace lagrange {
24namespace internal {
25LAGRANGE_LEGACY_INLINE
26namespace legacy {
27
42template <typename MeshType, typename DistFunc, typename ProcessFunc>
43void dijkstra(
44 const MeshType& mesh,
45 const std::vector<typename MeshType::Index>& seed_vertices,
46 const std::vector<typename MeshType::Scalar>& seed_vertex_dist,
47 typename MeshType::Scalar radius,
48 const DistFunc& dist,
49 const ProcessFunc& process)
50{
51 using Scalar = typename MeshType::Scalar;
52 using Index = typename MeshType::Index;
53
55 mesh.get_vertex_per_facet() == 3,
56 "Only triangle meshes are supported for now.");
58 mesh.is_connectivity_initialized(),
59 "BSF requires mesh connectivity to be initialized.");
60
61 if (radius <= 0.0) {
62 radius = std::numeric_limits<Scalar>::max();
63 }
64
65 const Index num_vertices = mesh.get_num_vertices();
66
67 using Entry = std::pair<Index, Scalar>;
68 auto comp = [](const Entry& e1, const Entry& e2) { return e1.second > e2.second; };
69 std::priority_queue<Entry, std::vector<Entry>, decltype(comp)> Q(comp);
70 std::vector<bool> visited(num_vertices, false);
71
72 size_t num_seeds = seed_vertices.size();
74 num_seeds == seed_vertex_dist.size(),
75 "Inconsistent number of seed distances.");
76 for (size_t i = 0; i < num_seeds; i++) {
77 la_runtime_assert(seed_vertices[i] < num_vertices);
78 Q.push({seed_vertices[i], seed_vertex_dist[i]});
79 }
80
81 while (!Q.empty()) {
82 Entry entry = Q.top();
83 Q.pop();
84
85 Index vi = entry.first;
86 Scalar di = entry.second;
87
88 if (visited[vi]) continue;
89
90 bool done = process(vi, di);
91 if (done) break;
92 visited[vi] = true;
93
94 const auto& adj_vertices = mesh.get_vertices_adjacent_to_vertex(entry.first);
95 for (const auto& vj : adj_vertices) {
96 Scalar dj = di + dist(vi, vj);
97 if (dj < radius) {
98 Q.push({vj, dj});
99 }
100 }
101 }
102}
103
104} // namespace legacy
105} // namespace internal
106} // namespace lagrange
Definition: Mesh.h:48
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
void dijkstra(SurfaceMesh< Scalar, Index > &mesh, span< const Index > seed_vertices, span< const Scalar > seed_vertex_dist, Scalar radius, const function_ref< Scalar(Index, Index)> &dist, const function_ref< bool(Index, Scalar)> &process)
Traverse the mesh based on Dijkstra's algorithm with customized distance metric and process functions...
Definition: dijstra.cpp:24
Main namespace for Lagrange.
Definition: AABBIGL.h:30