Skip to content

Commit ea1e8f0

Browse files
authored
Merge pull request #297 from akaszynski/feat/add-is_intrinsic_delaunay
Add is_intrinsic_delaunay function
2 parents 0918771 + ae6c999 commit ea1e8f0

2 files changed

Lines changed: 94 additions & 0 deletions

File tree

src/is_intrinsic_delaunay.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include "default_types.h"
2+
#include <igl/is_intrinsic_delaunay.h>
3+
#include <nanobind/nanobind.h>
4+
#include <nanobind/ndarray.h>
5+
#include <nanobind/eigen/dense.h>
6+
7+
namespace nb = nanobind;
8+
using namespace nb::literals;
9+
namespace pyigl
10+
{
11+
auto is_intrinsic_delaunay(
12+
const nb::DRef<const Eigen::MatrixXN> &l,
13+
const nb::DRef<const Eigen::MatrixXI> &F)
14+
{
15+
Eigen::Matrix<unsigned char, Eigen::Dynamic, Eigen::Dynamic> D;
16+
igl::is_intrinsic_delaunay(l, F, D);
17+
return D;
18+
}
19+
}
20+
21+
void bind_is_intrinsic_delaunay(nb::module_ &m)
22+
{
23+
m.def("is_intrinsic_delaunay", &pyigl::is_intrinsic_delaunay,
24+
"l"_a,
25+
"F"_a,
26+
R"(Determine if each edge in the mesh (V,F) is Delaunay.
27+
@param[in] l #l by dim list of edge lengths
28+
@param[in] F #F by 3 list of triangles indices
29+
@param[out] D D #F by 3 list of bools revealing whether edges corresponding
30+
23 31 12 are locally Delaunay. Boundary edges are by definition Delaunay.
31+
Non-Manifold edges are by definition not Delaunay.
32+
)");
33+
}

tests/test_all.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,67 @@ def udf_sphere(Q):
606606
unique_S = sdf_sphere(unique_corners)
607607
V,F = igl.marching_cubes(unique_S,unique_corners,J,0.0)
608608

609+
def test_is_intrinsic_delaunay() -> None:
610+
# vs and fs come from a simple plane from pyvista
611+
# mesh = pv.Plane(i_resolution=3, j_resolution=2, i_size=2).triangulate()
612+
# fs = mesh._connectivity_array.reshape(-1, 3).astype(np.int32)
613+
# vs = mesh.points.astype(np.float64)
614+
615+
fs = np.array(
616+
[
617+
[0, 1, 4],
618+
[1, 5, 4],
619+
[1, 2, 5],
620+
[2, 6, 5],
621+
[2, 3, 6],
622+
[3, 7, 6],
623+
[4, 5, 8],
624+
[5, 9, 8],
625+
[5, 6, 9],
626+
[6, 10, 9],
627+
[6, 7, 10],
628+
[7, 11, 10],
629+
]
630+
)
631+
632+
vs = np.array(
633+
[
634+
[-1.0, -0.5, 0.0],
635+
[-0.33333334, -0.5, 0.0],
636+
[0.33333334, -0.5, 0.0],
637+
[1.0, -0.5, 0.0],
638+
[-1.0, 0.0, 0.0],
639+
[-0.33333334, 0.0, 0.0],
640+
[0.33333334, 0.0, 0.0],
641+
[1.0, 0.0, 0.0],
642+
[-1.0, 0.5, 0.0],
643+
[-0.33333334, 0.5, 0.0],
644+
[0.33333334, 0.5, 0.0],
645+
[1.0, 0.5, 0.0],
646+
]
647+
)
648+
649+
lin = igl.edge_lengths(vs, fs)
650+
mask = igl.is_intrinsic_delaunay(lin, fs).astype(bool)
651+
652+
expected_mask = np.array(
653+
[
654+
[0, 1, 1],
655+
[1, 0, 1],
656+
[1, 1, 1],
657+
[1, 1, 1],
658+
[0, 1, 1],
659+
[1, 0, 1],
660+
[0, 1, 1],
661+
[1, 0, 1],
662+
[1, 1, 1],
663+
[1, 1, 1],
664+
[0, 1, 1],
665+
[1, 0, 1],
666+
]
667+
)
668+
assert np.array_equal(mask, expected_mask)
669+
609670
def test_rotate_vectors(icosahedron):
610671
V,F = icosahedron
611672

0 commit comments

Comments
 (0)