Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions src/connect_boundary_to_infinity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include "default_types.h"
#include <igl/connect_boundary_to_infinity.h>
#include <nanobind/nanobind.h>
#include <nanobind/ndarray.h>
#include <nanobind/eigen/dense.h>
#include <nanobind/stl/tuple.h>

namespace nb = nanobind;
using namespace nb::literals;

namespace pyigl
{
auto connect_boundary_to_infinity_F(
const nb::DRef<const Eigen::MatrixXI> &F)
{
Eigen::MatrixXI FO;
igl::connect_boundary_to_infinity(F, FO);
return FO;
}

auto connect_boundary_to_infinity_VF(
const nb::DRef<const Eigen::MatrixXN> &V,
const nb::DRef<const Eigen::MatrixXI> &F)
{
Eigen::MatrixXN VO;
Eigen::MatrixXI FO;
igl::connect_boundary_to_infinity(V, F, VO, FO);
return std::make_tuple(VO, FO);
}
}

void bind_connect_boundary_to_infinity(nb::module_ &m)
{
m.def(
"connect_boundary_to_infinity",
&pyigl::connect_boundary_to_infinity_F,
"F"_a,
R"(Connect all boundary edges to a fictitious point at infinity, closing an
open mesh (the result is edge-manifold if the input was manifold).

@param[in] F #F by 3 list of face indices into some V
@param[out] FO #F+#O by 3 list of face indices into [V; inf], original F come
first)");
m.def(
"connect_boundary_to_infinity",
&pyigl::connect_boundary_to_infinity_VF,
"V"_a,
"F"_a,
R"(Connect all boundary edges to a fictitious point at infinity, also
returning the augmented vertex list.

@param[in] V #V by 3 list of vertex positions
@param[in] F #F by 3 list of face indices into rows of V
@param[out] VO #V+1 by 3 list of vertex positions; original V come first and
the last row is (inf, inf, inf)
@param[out] FO #F+#O by 3 list of face indices into rows of VO)");
}
35 changes: 35 additions & 0 deletions src/fit_rotations.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "default_types.h"
#include <igl/fit_rotations.h>
#include <nanobind/nanobind.h>
#include <nanobind/ndarray.h>
#include <nanobind/eigen/dense.h>

namespace nb = nanobind;
using namespace nb::literals;

namespace pyigl
{
auto fit_rotations(
const nb::DRef<const Eigen::MatrixXN> &S,
const bool single_precision)
{
Eigen::MatrixXN R;
igl::fit_rotations(S, single_precision, R);
return R;
}
}

void bind_fit_rotations(nb::module_ &m)
{
m.def(
"fit_rotations",
&pyigl::fit_rotations,
"S"_a,
"single_precision"_a = false,
R"(Given a stack of covariance matrices, find the closest rotation to each
(e.g. the local step of an as-rigid-as-possible optimization).

@param[in] S (n*dim) by dim stack of covariance matrices
@param[in] single_precision whether to use single precision (faster)
@param[out] R dim by (dim*n) list of rotations)");
}
35 changes: 35 additions & 0 deletions src/path_to_edges.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "default_types.h"
#include <igl/path_to_edges.h>
#include <nanobind/nanobind.h>
#include <nanobind/ndarray.h>
#include <nanobind/eigen/dense.h>

namespace nb = nanobind;
using namespace nb::literals;

namespace pyigl
{
auto path_to_edges(
const nb::DRef<const Eigen::VectorXI> &I,
const bool make_loop)
{
Eigen::MatrixXI E;
igl::path_to_edges(I, E, make_loop);
return E;
}
}

void bind_path_to_edges(nb::module_ &m)
{
m.def(
"path_to_edges",
&pyigl::path_to_edges,
"I"_a,
"make_loop"_a = false,
R"(Given an ordered list of vertex indices describing a path, return the list
of undirected edges connecting consecutive entries.

@param[in] I #I list of vertex indices along the path
@param[in] make_loop whether to also connect the last vertex back to the first
@param[out] E #E by 2 list of edges (E = #I-1, or #I if make_loop))");
}
43 changes: 43 additions & 0 deletions src/planarize_quad_mesh.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "default_types.h"
#include <igl/planarize_quad_mesh.h>
#include <nanobind/nanobind.h>
#include <nanobind/ndarray.h>
#include <nanobind/eigen/dense.h>

namespace nb = nanobind;
using namespace nb::literals;

namespace pyigl
{
auto planarize_quad_mesh(
const nb::DRef<const Eigen::MatrixXN> &Vin,
const nb::DRef<const Eigen::MatrixXI> &F,
const int maxIter,
const Numeric threshold)
{
// Vout must share Vin's (deduced) type, so pass a concrete copy of the input
Eigen::MatrixXN Vin_copy = Vin;
Eigen::MatrixXN Vout;
igl::planarize_quad_mesh(Vin_copy, F, maxIter, threshold, Vout);
return Vout;
}
}

void bind_planarize_quad_mesh(nb::module_ &m)
{
m.def(
"planarize_quad_mesh",
&pyigl::planarize_quad_mesh,
"Vin"_a,
"F"_a,
"maxIter"_a = 100,
"threshold"_a = 0.005,
R"(Planarize a quad mesh, moving vertices so that each quad becomes as planar
as possible while staying close to the original surface.

@param[in] Vin #V by 3 list of input mesh vertex positions
@param[in] F #F by 4 list of quad face indices into rows of Vin
@param[in] maxIter maximum number of optimization iterations
@param[in] threshold planarity threshold at which to stop
@param[out] Vout #V by 3 list of planarized vertex positions)");
}
64 changes: 64 additions & 0 deletions src/point_simplex_squared_distance.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "default_types.h"
#include <igl/point_simplex_squared_distance.h>
#include <nanobind/nanobind.h>
#include <nanobind/ndarray.h>
#include <nanobind/eigen/dense.h>
#include <nanobind/stl/tuple.h>

namespace nb = nanobind;
using namespace nb::literals;

namespace pyigl
{
auto point_simplex_squared_distance(
const nb::DRef<const Eigen::RowVectorXN> &p,
const nb::DRef<const Eigen::MatrixXN> &V,
const nb::DRef<const Eigen::MatrixXI> &Ele,
const Integer i)
{
// Use concrete Eigen types (template deduction is finicky with DRef maps here).
// DIM (the ambient dimension) is a non-deduced template parameter, so we must
// supply it explicitly; dispatch on the number of columns of V.
const Eigen::RowVectorXN pc = p;
const Eigen::MatrixXN Vc = V;
const Eigen::MatrixXI Elec = Ele;
Numeric sqr_d;
Eigen::RowVectorXN c;
Eigen::RowVectorXN b;
switch (Vc.cols())
{
case 2:
igl::point_simplex_squared_distance<2>(pc, Vc, Elec, i, sqr_d, c, b);
break;
case 3:
igl::point_simplex_squared_distance<3>(pc, Vc, Elec, i, sqr_d, c, b);
break;
default:
throw std::runtime_error(
"point_simplex_squared_distance: only 2D and 3D points are supported");
}
return std::make_tuple(sqr_d, c, b);
}
}

void bind_point_simplex_squared_distance(nb::module_ &m)
{
m.def(
"point_simplex_squared_distance",
&pyigl::point_simplex_squared_distance,
"p"_a,
"V"_a,
"Ele"_a,
"i"_a,
R"(Determine the squared distance from a point p to the i-th linear simplex
(point/segment/triangle) of a mesh, along with the closest point and its
barycentric coordinates.

@param[in] p dim-long query point
@param[in] V #V by dim list of simplex-corner vertex positions
@param[in] Ele #Ele by (1|2|3) list of simplex indices into rows of V
@param[in] i index of the simplex (row of Ele) to measure against
@param[out] sqr_d squared distance from p to the i-th simplex
@param[out] c dim-long closest point on the i-th simplex
@param[out] b barycentric coordinates of the closest point c)");
}
32 changes: 32 additions & 0 deletions src/polar_svd3x3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "default_types.h"
#include <igl/polar_svd3x3.h>
#include <nanobind/nanobind.h>
#include <nanobind/ndarray.h>
#include <nanobind/eigen/dense.h>

namespace nb = nanobind;
using namespace nb::literals;

namespace pyigl
{
auto polar_svd3x3(const nb::DRef<const Eigen::MatrixXN> &A)
{
Eigen::Matrix<Numeric, 3, 3> Am = A;
Eigen::Matrix<Numeric, 3, 3> R;
igl::polar_svd3x3(Am, R);
return Eigen::MatrixXN(R);
}
}

void bind_polar_svd3x3(nb::module_ &m)
{
m.def(
"polar_svd3x3",
&pyigl::polar_svd3x3,
"A"_a,
R"(Compute the closest rotation matrix R to a 3x3 matrix A via the polar
decomposition (using a fast fixed-size SVD).

@param[in] A 3 by 3 matrix
@param[out] R 3 by 3 closest rotation matrix (det(R) = +1))");
}
33 changes: 33 additions & 0 deletions src/quad_edges.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "default_types.h"
#include <igl/quad_edges.h>
#include <nanobind/nanobind.h>
#include <nanobind/ndarray.h>
#include <nanobind/eigen/dense.h>

namespace nb = nanobind;
using namespace nb::literals;

namespace pyigl
{
auto quad_edges(const nb::DRef<const Eigen::MatrixXI> &Q)
{
// igl::quad_edges is instantiated only for 32-bit int matrices (it builds an
// Eigen::MatrixXi internally), so cast to int and back.
Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic> Qi = Q.cast<int>();
Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic> Ei;
igl::quad_edges(Qi, Ei);
return Eigen::MatrixXI(Ei.cast<Integer>());
}
}

void bind_quad_edges(nb::module_ &m)
{
m.def(
"quad_edges",
&pyigl::quad_edges,
"Q"_a,
R"(Compute the list of unique undirected edges of a quad mesh.

@param[in] Q #Q by 4 list of quad face indices
@param[out] E #E by 2 list of unique edges)");
}
36 changes: 36 additions & 0 deletions src/quad_planarity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "default_types.h"
#include <igl/quad_planarity.h>
#include <nanobind/nanobind.h>
#include <nanobind/ndarray.h>
#include <nanobind/eigen/dense.h>

namespace nb = nanobind;
using namespace nb::literals;

namespace pyigl
{
auto quad_planarity(
const nb::DRef<const Eigen::MatrixXN> &V,
const nb::DRef<const Eigen::MatrixXI> &F)
{
Eigen::VectorXN P;
igl::quad_planarity(V, F, P);
return P;
}
}

void bind_quad_planarity(nb::module_ &m)
{
m.def(
"quad_planarity",
&pyigl::quad_planarity,
"V"_a,
"F"_a,
R"(Compute a planarity value for each quad in a quad mesh. Planarity is the
distance between the two diagonals of the quad divided by the average of the
diagonals' lengths (0 for a perfectly planar quad).

@param[in] V #V by 3 list of mesh vertex positions
@param[in] F #F by 4 list of quad face indices into rows of V
@param[out] P #F list of planarity values)");
}
38 changes: 38 additions & 0 deletions src/ramer_douglas_peucker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "default_types.h"
#include <igl/ramer_douglas_peucker.h>
#include <nanobind/nanobind.h>
#include <nanobind/ndarray.h>
#include <nanobind/eigen/dense.h>
#include <nanobind/stl/tuple.h>

namespace nb = nanobind;
using namespace nb::literals;

namespace pyigl
{
auto ramer_douglas_peucker(
const nb::DRef<const Eigen::MatrixXN> &P,
const Numeric tol)
{
Eigen::MatrixXN S;
Eigen::VectorXI J;
igl::ramer_douglas_peucker(P, tol, S, J);
return std::make_tuple(S, J);
}
}

void bind_ramer_douglas_peucker(nb::module_ &m)
{
m.def(
"ramer_douglas_peucker",
&pyigl::ramer_douglas_peucker,
"P"_a,
"tol"_a,
R"(Ramer-Douglas-Peucker piecewise-linear curve simplification.

@param[in] P #P by dim ordered list of vertices along the curve
@param[in] tol tolerance (maximal Euclidean distance allowed between the new
line and a removed vertex)
@param[out] S #S by dim ordered list of points along the simplified curve
@param[out] J #S list of indices into P so that S = P[J,:])");
}
Loading
Loading