diff --git a/src/edges_to_path.cpp b/src/edges_to_path.cpp new file mode 100644 index 00000000..e6819c7e --- /dev/null +++ b/src/edges_to_path.cpp @@ -0,0 +1,56 @@ +#include "default_types.h" +#include +#include +#include +#include + +namespace nb = nanobind; +using namespace nb::literals; + +namespace pyigl +{ + // Wrapper for igl::edges_to_path + auto edges_to_path(const nb::DRef &E) + { + // libigl's implementation internally maps to an int-backed buffer, + // so ensure the input scalar type is 32-bit int to avoid Map pointer mismatches. + using MatXI32 = Eigen::Matrix; + using VecXI32 = Eigen::Matrix; + + MatXI32 Ei = E.template cast(); + VecXI32 Ii, Ji, Ki; + igl::edges_to_path(Ei, Ii, Ji, Ki); + + Eigen::VectorXI I = Ii.template cast(); + Eigen::VectorXI J = Ji.template cast(); + Eigen::VectorXI K = Ki.template cast(); + return std::make_tuple(I, J, K); + } +} + +// Bind the wrapper to the Python module +void bind_edges_to_path(nb::module_ &m) +{ + m.def( + "edges_to_path", + &pyigl::edges_to_path, + "E"_a, +R"(Given a set of undirected, unique edges such that all form a +single connected component with exactly 0 or 2 nodes with valence = 1, +determine a path visiting all nodes. + +Parameters +---------- +E : (#E, 2) int array + Undirected edges + +Returns +------- +I : (#E+1,) int array + Nodes in order tracing the chain (loop). If the output is a loop then I[0] == I[-1] +J : (#I-1,) int array + Indices into E of edges tracing I +K : (#I-1,) int array in {0,1} + Column indices so that I[i] == E[J[i], K[i]] for i < len(I)-1)" + ); +} diff --git a/tests/test_all.py b/tests/test_all.py index c9af717c..8a703c72 100644 --- a/tests/test_all.py +++ b/tests/test_all.py @@ -164,7 +164,12 @@ def test_harmonic_integrated_from_laplacian_and_mass(): M = igl.massmatrix(V, F, igl.MASSMATRIX_TYPE_VORONOI) Q = igl.harmonic_integrated_from_laplacian_and_mass(L, M, k=1) Q = igl.harmonic_integrated_from_laplacian_and_mass(L, M, k=2) - + +def test_edges_to_path(): + V,F = triangulated_square() + E, D, G = igl.boundary_facets(F) + _,_,_ = igl.edges_to_path(E) + def test_tets(): V,F,T = single_tet() F,J,K = igl.boundary_facets(T)