|
| 1 | +#include "default_types.h" |
| 2 | +#include <igl/dijkstra.h> |
| 3 | +#include <nanobind/nanobind.h> |
| 4 | +#include <nanobind/eigen/dense.h> |
| 5 | +#include <nanobind/stl/tuple.h> |
| 6 | +#include <nanobind/stl/vector.h> |
| 7 | +#include <nanobind/stl/set.h> |
| 8 | + |
| 9 | +namespace nb = nanobind; |
| 10 | +using namespace nb::literals; |
| 11 | + |
| 12 | +namespace pyigl |
| 13 | +{ |
| 14 | + // Dijkstra with uniform edge weights (Euclidean distance via vertex positions) |
| 15 | + auto dijkstra( |
| 16 | + const nb::DRef<const Eigen::MatrixXN> &V, |
| 17 | + const std::vector<std::vector<Integer>> &VV, |
| 18 | + const Integer source, |
| 19 | + const std::set<Integer> &targets) |
| 20 | + { |
| 21 | + Eigen::VectorXN min_distance; |
| 22 | + Eigen::VectorXI previous; |
| 23 | + igl::dijkstra(V, VV, source, targets, min_distance, previous); |
| 24 | + return std::make_tuple(min_distance, previous); |
| 25 | + } |
| 26 | + // Dijkstra with custom vertex weights |
| 27 | + auto dijkstra_weighted( |
| 28 | + const Integer source, |
| 29 | + const std::set<Integer> &targets, |
| 30 | + const std::vector<std::vector<Integer>> &VV, |
| 31 | + const std::vector<double> &weights) |
| 32 | + { |
| 33 | + Eigen::VectorXN min_distance; |
| 34 | + Eigen::VectorXI previous; |
| 35 | + igl::dijkstra(source, targets, VV, weights, min_distance, previous); |
| 36 | + return std::make_tuple(min_distance, previous); |
| 37 | + } |
| 38 | + // Backtrack path from vertex to source |
| 39 | + auto dijkstra_backtrack( |
| 40 | + const Integer vertex, |
| 41 | + const nb::DRef<const Eigen::MatrixXI> &previous) |
| 42 | + { |
| 43 | + // previous[i] single-index access requires IsVectorAtCompileTime — copy to VectorXI |
| 44 | + const Eigen::VectorXI prev = previous.reshaped(); |
| 45 | + std::vector<Integer> path; |
| 46 | + igl::dijkstra(vertex, prev, path); |
| 47 | + Eigen::VectorXI result(path.size()); |
| 48 | + for (size_t i = 0; i < path.size(); ++i) result(i) = path[i]; |
| 49 | + return result; |
| 50 | + } |
| 51 | +} |
| 52 | + |
| 53 | +void bind_dijkstra(nb::module_ &m) |
| 54 | +{ |
| 55 | + m.def("dijkstra", &pyigl::dijkstra, |
| 56 | + "V"_a, "VV"_a, "source"_a, "targets"_a, |
| 57 | + R"(Dijkstra shortest paths using Euclidean edge weights. |
| 58 | +
|
| 59 | +@param[in] V #V by 3 list of vertex positions |
| 60 | +@param[in] VV #V list of adjacency lists (e.g. from adjacency_list) |
| 61 | +@param[in] source source vertex index |
| 62 | +@param[in] targets set of target vertex indices (stop early if reached) |
| 63 | +@return min_distance #V list of minimum distances from source |
| 64 | +@return previous #V list of previous vertex indices for path reconstruction)"); |
| 65 | + |
| 66 | + m.def("dijkstra", &pyigl::dijkstra_weighted, |
| 67 | + "source"_a, "targets"_a, "VV"_a, "weights"_a, |
| 68 | + R"(Dijkstra shortest paths with custom vertex weights. |
| 69 | +
|
| 70 | +@param[in] source source vertex index |
| 71 | +@param[in] targets set of target vertex indices |
| 72 | +@param[in] VV #V list of adjacency lists |
| 73 | +@param[in] weights #V list of vertex weights |
| 74 | +@return min_distance #V list of minimum distances from source |
| 75 | +@return previous #V list of previous vertex indices)"); |
| 76 | + |
| 77 | + m.def("dijkstra_backtrack", &pyigl::dijkstra_backtrack, |
| 78 | + "vertex"_a, "previous"_a, |
| 79 | + R"(Backtrack path from a vertex to the source using Dijkstra's previous array. |
| 80 | +
|
| 81 | +@param[in] vertex destination vertex |
| 82 | +@param[in] previous #V list of previous vertex indices (from dijkstra) |
| 83 | +@return path list of vertex indices from vertex to source)"); |
| 84 | +} |
0 commit comments