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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ external
bin
bin_rel
build
build-full

tutorial/data
tutorial/.ipynb_*
Expand Down
18 changes: 17 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(nanobind)

# Pin Eigen to 3.4.0. Recent libigl bumped its Eigen dependency to 5.0.1, whose
# stricter ScalarBinaryOpTraits rejects the int64-vs-int comparisons in some
# libigl headers (e.g. unique_edge_map), which the 64-bit-index Python bindings
# instantiate. Declaring Eigen first makes FetchContent use this version instead
# of the one requested by libigl's own recipe.
FetchContent_Declare(
eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG tags/3.4.0
GIT_SHALLOW TRUE
)

# Download and set up libigl
option(LIBIGL_COPYLEFT_CORE "Build target igl_copyleft::core" ON)
option(LIBIGL_COPYLEFT_CGAL "Build target igl_copyleft::cgal" ON)
Expand All @@ -44,10 +56,11 @@ option(LIBIGL_COPYLEFT_TETGEN "Build target igl_copyleft::tetgen" ON)
option(LIBIGL_RESTRICTED_TRIANGLE "Build target igl_restricted::triangle" ON)
option(LIBIGL_SPECTRA "Build igl::spectra bindings" ON)
option(LIBIGL_PREDICATES "Build igl::predicates bindings" ON)
option(LIBIGL_CYCODEBASE "Build igl::cycodebase bindings" ON)
FetchContent_Declare(
libigl
GIT_REPOSITORY https://github.com/libigl/libigl.git
GIT_TAG 678e1fff76815e0c4c5d1f025ee2129181cc7d86
GIT_TAG 477e15a3d566a21f415aa5ee62992b12a836b01b
)
FetchContent_MakeAvailable(libigl)

Expand Down Expand Up @@ -190,6 +203,9 @@ endif()
if(LIBIGL_PREDICATES)
pyigl_include("" "predicates")
endif()
if(LIBIGL_CYCODEBASE)
pyigl_include("" "cycodebase")
endif()



2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ build-backend = "scikit_build_core.build"

[project]
name = "libigl"
version = "2.6.3.dev3"
version = "2.6.3.dev4"
description = "libigl: A simple C++ geometry processing library"
readme = "README.md"
requires-python = ">=3.8"
Expand Down
29 changes: 29 additions & 0 deletions src/cubic.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "default_types.h"
#include <igl/cubic.h>
#include <nanobind/nanobind.h>
#include <nanobind/eigen/dense.h>

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

namespace pyigl
{
auto cubic(
const nb::DRef<const Eigen::MatrixXN> &C,
const Numeric t)
{
Eigen::MatrixXN P;
igl::cubic(C, t, P);
return P;
}
}

void bind_cubic(nb::module_ &m)
{
m.def("cubic", &pyigl::cubic, "C"_a, "t"_a,
R"(Evaluate a cubic Bézier curve defined by control points C at parameter t.

@param[in] C 4 by dim matrix of control points for a cubic Bézier curve
@param[in] t parameter at which to evaluate the curve
@return P 1 by dim point on the curve C(t))");
}
31 changes: 31 additions & 0 deletions src/cubic_is_flat.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "default_types.h"
#include <igl/cubic_is_flat.h>
#include <nanobind/nanobind.h>
#include <nanobind/eigen/dense.h>

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

namespace pyigl
{
bool cubic_is_flat(
const nb::DRef<const Eigen::MatrixXN> &C,
const Numeric squared_distance_bound)
{
return igl::cubic_is_flat(C, squared_distance_bound);
}
}

void bind_cubic_is_flat(nb::module_ &m)
{
m.def("cubic_is_flat", &pyigl::cubic_is_flat, "C"_a, "squared_distance_bound"_a,
R"(Test whether a cubic Bézier curve is flat within a given tolerance.

"Piecewise Linear Approximation of Bézier Curves" [Fischer 2000]. If the test
passes, the curve's maximum squared distance to the chord from its first to its
last control point is less than squared_distance_bound.

@param[in] C 4 by dim matrix of control points for a cubic Bézier curve
@param[in] squared_distance_bound squared distance tolerance
@return True if the curve is flat within the given tolerance)");
}
35 changes: 35 additions & 0 deletions src/cubic_monomial_bases.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "default_types.h"
#include <igl/cubic_monomial_bases.h>
#include <nanobind/nanobind.h>
#include <nanobind/eigen/dense.h>
#include <nanobind/stl/tuple.h>
#include <tuple>

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

namespace pyigl
{
auto cubic_monomial_bases(
const nb::DRef<const Eigen::MatrixXN> &C)
{
Eigen::MatrixXN M, D;
// B is a 6-vector of inner products (cubic_monomial_bases calls vector
// methods on it), so it must be a vector type, not a general matrix.
Eigen::VectorXN B;
igl::cubic_monomial_bases(C, M, D, B);
return std::make_tuple(M, D, B);
}
}

void bind_cubic_monomial_bases(nb::module_ &m)
{
m.def("cubic_monomial_bases", &pyigl::cubic_monomial_bases, "C"_a,
R"(Compute monomial basis representations for a cubic Bézier curve.

@param[in] C 4 by dim matrix of control points for a cubic Bézier curve
@return Tuple (M, D, B) where
M 4 by dim matrix of monomial coefficients for C(t)
D 3 by dim matrix of monomial coefficients for dC/dt
B 6-vector of inner products of those basis functions for C(t))");
}
33 changes: 33 additions & 0 deletions src/cubic_split.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "default_types.h"
#include <igl/cubic_split.h>
#include <nanobind/nanobind.h>
#include <nanobind/eigen/dense.h>
#include <nanobind/stl/tuple.h>
#include <tuple>

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

namespace pyigl
{
auto cubic_split(
const nb::DRef<const Eigen::MatrixXN> &C,
const Numeric t)
{
Eigen::MatrixXN C1, C2;
igl::cubic_split(C, t, C1, C2);
return std::make_tuple(C1, C2);
}
}

void bind_cubic_split(nb::module_ &m)
{
m.def("cubic_split", &pyigl::cubic_split, "C"_a, "t"_a,
R"(Split a cubic Bézier curve at parameter t into two cubic Bézier curves.

@param[in] C 4 by dim matrix of control points for a cubic Bézier curve
@param[in] t parameter at which to split the curve
@return Tuple (C1, C2) where
C1 4 by dim control points of the sub-curve from C(0) to C(t)
C2 4 by dim control points of the sub-curve from C(t) to C(1))");
}
50 changes: 50 additions & 0 deletions src/cycodebase/box_cubic.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "default_types.h"
#include <igl/cycodebase/box_cubic.h>
#include <nanobind/nanobind.h>
#include <nanobind/eigen/dense.h>
#include <nanobind/stl/tuple.h>
#include <tuple>

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

namespace pyigl
{
// Bounding box of a single cubic Bézier curve.
auto box_cubic_C(
const nb::DRef<const Eigen::MatrixXN> &C)
{
Eigen::RowVectorXN B1, B2;
igl::cycodebase::box_cubic(C, B1, B2);
return std::make_tuple(B1, B2);
}
// Bounding boxes of many indexed cubic Bézier curves.
auto box_cubic_PC(
const nb::DRef<const Eigen::MatrixXN> &P,
const nb::DRef<const Eigen::MatrixXI> &C)
{
Eigen::MatrixXN B1, B2;
igl::cycodebase::box_cubic(P, C, B1, B2);
return std::make_tuple(B1, B2);
}
}

void bind_box_cubic(nb::module_ &m)
{
m.def("box_cubic", &pyigl::box_cubic_C, "C"_a,
R"(Compute the min/max box corners tightly containing a cubic Bézier curve.

@param[in] C 4 by dim matrix of control points defining the cubic Bézier curve
@return Tuple (B1, B2) where
B1 1 by dim min corner of the bounding box
B2 1 by dim max corner of the bounding box)");

m.def("box_cubic", &pyigl::box_cubic_PC, "P"_a, "C"_a,
R"(Compute bounding boxes for a collection of indexed cubic Bézier curves.

@param[in] P #P by dim matrix of control point locations
@param[in] C #C by 4 matrix of indices into P defining the cubics
@return Tuple (B1, B2) where
B1 #C by dim matrix of min corners of the bounding boxes
B2 #C by dim matrix of max corners of the bounding boxes)");
}
11 changes: 11 additions & 0 deletions src/cycodebase/module.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <nanobind/nanobind.h>
namespace nb = nanobind;

// generated by cmake
#include "cycodebase/BINDING_DECLARATIONS.in"

NB_MODULE(pyigl_cycodebase, m) {
m.doc() = "libigl cycodebase module python bindings";
// generated by cmake
#include "cycodebase/BINDING_INVOCATIONS.in"
}
36 changes: 36 additions & 0 deletions src/cycodebase/point_cubic_squared_distance.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "default_types.h"
#include <igl/cycodebase/point_cubic_squared_distance.h>
#include <nanobind/nanobind.h>
#include <nanobind/eigen/dense.h>
#include <nanobind/stl/tuple.h>
#include <tuple>

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

namespace pyigl
{
auto point_cubic_squared_distance(
const nb::DRef<const Eigen::MatrixXN> &Q,
const nb::DRef<const Eigen::MatrixXN> &C)
{
Eigen::VectorXN sqrD, S;
Eigen::MatrixXN K;
igl::cycodebase::point_cubic_squared_distance(Q, C, sqrD, S, K);
return std::make_tuple(sqrD, S, K);
}
}

void bind_point_cubic_squared_distance(nb::module_ &m)
{
m.def("point_cubic_squared_distance", &pyigl::point_cubic_squared_distance,
"Q"_a, "C"_a,
R"(Squared distance from each query point to a cubic Bézier curve.

@param[in] Q #Q by dim matrix of query points
@param[in] C 4 by dim matrix of control points for the cubic Bézier curve
@return Tuple (sqrD, S, K) where
sqrD #Q vector of smallest squared distances
S #Q vector of parameters of the closest points on the curve
K #Q by dim matrix of closest points on the curve)");
}
40 changes: 40 additions & 0 deletions src/cycodebase/point_spline_squared_distance.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "default_types.h"
#include <igl/cycodebase/point_spline_squared_distance.h>
#include <nanobind/nanobind.h>
#include <nanobind/eigen/dense.h>
#include <nanobind/stl/tuple.h>
#include <tuple>

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

namespace pyigl
{
auto point_spline_squared_distance(
const nb::DRef<const Eigen::MatrixXN> &Q,
const nb::DRef<const Eigen::MatrixXN> &P,
const nb::DRef<const Eigen::MatrixXI> &C)
{
Eigen::VectorXN sqrD, S;
Eigen::VectorXI I;
Eigen::MatrixXN K;
igl::cycodebase::point_spline_squared_distance(Q, P, C, sqrD, I, S, K);
return std::make_tuple(sqrD, I, S, K);
}
}

void bind_point_spline_squared_distance(nb::module_ &m)
{
m.def("point_spline_squared_distance", &pyigl::point_spline_squared_distance,
"Q"_a, "P"_a, "C"_a,
R"(Squared distance from each query point to a spline of cubic Bézier curves.

@param[in] Q #Q by dim matrix of query points
@param[in] P #P by dim matrix of spline control points
@param[in] C #C by 4 matrix of indices into P defining the cubic Bézier curves
@return Tuple (sqrD, I, S, K) where
sqrD #Q vector of smallest squared distances
I #Q vector of indices of the closest cubic (row of C)
S #Q vector of parameters of the closest points on that cubic
K #Q by dim matrix of closest points on the spline)");
}
39 changes: 39 additions & 0 deletions src/cycodebase/roots.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "default_types.h"
#include <igl/cycodebase/roots.h>
#include <nanobind/nanobind.h>
#include <nanobind/eigen/dense.h>
#include <nanobind/stl/tuple.h>
#include <tuple>

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

namespace pyigl
{
auto roots(
const nb::DRef<const Eigen::VectorXN> &coef_in,
const Numeric xmin,
const Numeric xmax)
{
// Copy to a contiguous vector of monomial coefficients (low to high).
const Eigen::VectorXN coef = coef_in;
Eigen::VectorXN R;
const int nr = igl::cycodebase::roots(coef, xmin, xmax, R);
return std::make_tuple(nr, R);
}
}

void bind_roots(nb::module_ &m)
{
m.def("roots", &pyigl::roots, "coef"_a, "xmin"_a, "xmax"_a,
R"(Find the real roots of a polynomial within an interval [xmin, xmax].

@param[in] coef #coef list of monomial coefficients (low to high order); the
polynomial degree is len(coef)-1
@param[in] xmin lower bound of the search interval
@param[in] xmax upper bound of the search interval
@return Tuple (n, R) where
n number of roots found in [xmin, xmax]
R degree-length vector whose first n entries are the roots (ascending); the
remaining entries are NaN)");
}
Loading
Loading