TTK
Loading...
Searching...
No Matches
Dijkstra.h
Go to the documentation of this file.
1#pragma once
2
3#include <Geometry.h>
4#include <Triangulation.h>
5
6#include <array>
7#include <functional>
8#include <limits>
9#include <queue>
10
11namespace ttk {
12 namespace Dijkstra {
24 template <typename T,
25 typename triangulationType = ttk::AbstractTriangulation>
26 int shortestPath(const SimplexId source,
27 const triangulationType &triangulation,
28 std::vector<T> &outputDists,
29 const std::vector<SimplexId> &bounds
30 = std::vector<SimplexId>(),
31 const std::vector<bool> &mask = std::vector<bool>()) {
32
33 // should we process the whole mesh or stop at some point?
34 bool const processAllVertices = bounds.empty();
35 // total number of vertices in the mesh
36 size_t const vertexNumber = triangulation.getNumberOfVertices();
37 // is there a mask?
38 bool const isMask = !mask.empty();
39
40 // check mask size
41 if(isMask && mask.size() != vertexNumber) {
42 return 1;
43 }
44
45 // list all reached bounds
46 std::vector<bool> reachedBounds;
47
48 // alloc and fill reachedBounds
49 if(!processAllVertices) {
50 reachedBounds.resize(bounds.size(), false);
51 }
52
53 // preprocess output vector
54 outputDists.clear();
55 outputDists.resize(vertexNumber, std::numeric_limits<T>::infinity());
56
57 // link vertex and current distance to source
58 using pq_t = std::pair<T, SimplexId>;
59
60 // priority queue storing pairs of (distance, vertices TTK id)
61 std::priority_queue<pq_t, std::vector<pq_t>, std::greater<pq_t>> pq;
62
63 // init pipeline
64 pq.push(std::make_pair(T(0.0F), source));
65 outputDists[source] = T(0.0F);
66
67 while(!pq.empty()) {
68 auto elem = pq.top();
69 pq.pop();
70 auto vert = elem.second;
71 std::array<float, 3> vCoords{};
72 triangulation.getVertexPoint(vert, vCoords[0], vCoords[1], vCoords[2]);
73
74 auto nneigh = triangulation.getVertexNeighborNumber(vert);
75
76 for(SimplexId i = 0; i < nneigh; i++) {
77 // neighbor Id
78 SimplexId neigh{};
79 triangulation.getVertexNeighbor(vert, i, neigh);
80
81 // limit to masked vertices
82 if(isMask && !mask[neigh]) {
83 continue;
84 }
85
86 // neighbor coordinates
87 std::array<float, 3> nCoords{};
88 triangulation.getVertexPoint(
89 neigh, nCoords[0], nCoords[1], nCoords[2]);
90 // (square) distance between vertex and neighbor
91 T distVN = Geometry::distance(vCoords.data(), nCoords.data());
92 if(outputDists[neigh] > outputDists[vert] + distVN) {
93 outputDists[neigh] = outputDists[vert] + distVN;
94 if(!processAllVertices) {
95 // check if neigh in bounds
96 auto it = std::find(bounds.begin(), bounds.end(), neigh);
97 if(it != bounds.end()) {
98 // mark it as found
99 reachedBounds[it - bounds.begin()] = true;
100 }
101 // break if all are found
102 if(std::all_of(reachedBounds.begin(), reachedBounds.end(),
103 [](const bool v) { return v; })) {
104 break;
105 }
106 }
107 pq.push(std::make_pair(outputDists[neigh], neigh));
108 }
109 }
110 }
111
112 return 0;
113 }
114
115 } // namespace Dijkstra
116} // namespace ttk
AbstractTriangulation is an interface class that defines an interface for efficient traversal methods...
virtual SimplexId getNumberOfVertices() const
int shortestPath(const SimplexId source, const triangulationType &triangulation, std::vector< T > &outputDists, const std::vector< SimplexId > &bounds=std::vector< SimplexId >(), const std::vector< bool > &mask=std::vector< bool >())
Compute the Dijkstra shortest path from source.
Definition Dijkstra.h:26
T distance(const T *p0, const T *p1, const int &dimension=3)
Definition Geometry.cpp:362
The Topology ToolKit.
int SimplexId
Identifier type for simplices of any dimension.
Definition DataTypes.h:22