Skip to content

Commit ae6c999

Browse files
authored
Merge branch 'main' into feat/add-is_intrinsic_delaunay
2 parents 9f8159d + 0918771 commit ae6c999

8 files changed

Lines changed: 440 additions & 2 deletions

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
[build-system]
22
requires = [
3-
"cmake>=3.16",
43
"nanobind >=1.3.2",
54
"numpy>=2.0.0; python_version >= '3.9'",
6-
"numpy; python_version < '3.9'",
5+
"numpy<2.0.0; python_version < '3.9'",
76
"packaging",
87
"scikit-build-core >=0.10",
98
"scipy",

src/comb_cross_field.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include "default_types.h"
2+
#include <igl/comb_cross_field.h>
3+
#include <nanobind/nanobind.h>
4+
#include <nanobind/ndarray.h>
5+
#include <nanobind/eigen/dense.h>
6+
#include <nanobind/stl/tuple.h>
7+
8+
namespace nb = nanobind;
9+
using namespace nb::literals;
10+
11+
void bind_comb_cross_field(nb::module_ &m)
12+
{
13+
m.def("comb_cross_field",
14+
[](
15+
const Eigen::MatrixXN& V,
16+
const Eigen::MatrixXI& F,
17+
const Eigen::MatrixXN& PD1,
18+
const Eigen::MatrixXN& PD2
19+
) {
20+
Eigen::MatrixXN PD1_out, PD2_out;
21+
igl::comb_cross_field(V, F, PD1, PD2, PD1_out, PD2_out);
22+
return std::make_tuple(PD1_out, PD2_out);
23+
},
24+
"V"_a,
25+
"F"_a,
26+
"PD1"_a,
27+
"PD2"_a,
28+
R"(Computes principal matchings of the vectors of a cross field across face edges,
29+
and generates a combed cross field defined on the mesh faces
30+
31+
@param[in] V #V by 3 eigen Matrix of mesh vertex 3D positions
32+
@param[in] F #F by 4 eigen Matrix of face (quad) indices
33+
@param[in] PD1in #F by 3 eigen Matrix of the first per face cross field vector
34+
@param[in] PD2in #F by 3 eigen Matrix of the second per face cross field vector
35+
@param[out] PD1out #F by 3 eigen Matrix of the first combed cross field vector
36+
@param[out] PD2out #F by 3 eigen Matrix of the second combed cross field vector
37+
)"
38+
);
39+
}

src/comb_frame_field.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include "default_types.h"
2+
#include <igl/comb_frame_field.h>
3+
#include <nanobind/nanobind.h>
4+
#include <nanobind/ndarray.h>
5+
#include <nanobind/eigen/dense.h>
6+
#include <nanobind/stl/tuple.h>
7+
8+
namespace nb = nanobind;
9+
using namespace nb::literals;
10+
11+
void bind_comb_frame_field(nb::module_ &m)
12+
{
13+
m.def("comb_frame_field",
14+
[](
15+
const Eigen::MatrixXN& V,
16+
const Eigen::MatrixXI& F,
17+
const Eigen::MatrixXN& PD1,
18+
const Eigen::MatrixXN& PD2,
19+
const Eigen::MatrixXN& BIS1_combed,
20+
const Eigen::MatrixXN& BIS2_combed
21+
) {
22+
Eigen::MatrixXN PD1_combed, PD2_combed;
23+
igl::comb_frame_field(V, F, PD1, PD2, BIS1_combed, BIS2_combed, PD1_combed, PD2_combed);
24+
return std::make_tuple(PD1_combed, PD2_combed);
25+
},
26+
"V"_a,
27+
"F"_a,
28+
"PD1"_a,
29+
"PD2"_a,
30+
"BIS1_combed"_a,
31+
"BIS2_combed"_a,
32+
R"(Computes principal matchings of the vectors of a frame field across face edges,
33+
and generates a combed frame field defined on the mesh faces. This makes use of a
34+
combed cross field generated by combing the field created by the bisectors of the
35+
frame field.
36+
37+
@param[in] V #V by 3 eigen Matrix of mesh vertex 3D positions
38+
@param[in] F #F by 4 eigen Matrix of face (quad) indices
39+
@param[in] PD1 #F by 3 eigen Matrix of the first per face cross field vector
40+
@param[in] PD2 #F by 3 eigen Matrix of the second per face cross field vector
41+
@param[in] BIS1_combed #F by 3 eigen Matrix of the first combed bisector field vector
42+
@param[in] BIS2_combed #F by 3 eigen Matrix of the second combed bisector field vector
43+
@param[out] PD1_combed #F by 3 eigen Matrix of the first combed cross field vector
44+
@param[out] PD2_combed #F by 3 eigen Matrix of the second combed cross field vector
45+
)"
46+
);
47+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#include "default_types.h"
2+
#include <igl/compute_frame_field_bisectors.h>
3+
#include <nanobind/nanobind.h>
4+
#include <nanobind/ndarray.h>
5+
#include <nanobind/eigen/dense.h>
6+
#include <nanobind/stl/tuple.h>
7+
8+
namespace nb = nanobind;
9+
using namespace nb::literals;
10+
11+
void bind_compute_frame_field_bisectors(nb::module_ &m)
12+
{
13+
m.def("compute_frame_field_bisectors",
14+
[](
15+
const Eigen::MatrixXN& V,
16+
const Eigen::MatrixXI& F,
17+
const Eigen::MatrixXN& B1,
18+
const Eigen::MatrixXN& B2,
19+
const Eigen::MatrixXN& PD1,
20+
const Eigen::MatrixXN& PD2
21+
) {
22+
Eigen::MatrixXN BIS1, BIS2;
23+
igl::compute_frame_field_bisectors(V, F, B1, B2, PD1, PD2, BIS1, BIS2);
24+
return std::make_tuple(BIS1, BIS2);
25+
},
26+
"V"_a,
27+
"F"_a,
28+
"B1"_a,
29+
"B2"_a,
30+
"PD1"_a,
31+
"PD2"_a,
32+
R"(Compute bisectors of a frame field defined on mesh faces.
33+
34+
@param[in] V #V by 3 eigen Matrix of mesh vertex 3D positions
35+
@param[in] F #F by 3 eigen Matrix of face (triangle) indices
36+
@param[in] B1 #F by 3 eigen Matrix of face (triangle) base vector 1
37+
@param[in] B2 #F by 3 eigen Matrix of face (triangle) base vector 2
38+
@param[in] PD1 #F by 3 eigen Matrix of the first per face frame field vector
39+
@param[in] PD2 #F by 3 eigen Matrix of the second per face frame field vector
40+
@param[out] BIS1 #F by 3 eigen Matrix of the first per face frame field bisector
41+
@param[out] BIS2 #F by 3 eigen Matrix of the second per face frame field bisector
42+
)"
43+
);
44+
45+
// Overload
46+
m.def("compute_frame_field_bisectors",
47+
[](
48+
const Eigen::MatrixXN& V,
49+
const Eigen::MatrixXI& F,
50+
const Eigen::MatrixXN& PD1,
51+
const Eigen::MatrixXN& PD2
52+
) {
53+
Eigen::MatrixXN BIS1, BIS2;
54+
igl::compute_frame_field_bisectors(V, F, PD1, PD2, BIS1, BIS2);
55+
return std::make_tuple(BIS1, BIS2);
56+
},
57+
"V"_a,
58+
"F"_a,
59+
"PD1"_a,
60+
"PD2"_a,
61+
R"(Compute bisectors of a frame field defined on mesh faces.
62+
63+
@param[in] V #V by 3 eigen Matrix of mesh vertex 3D positions
64+
@param[in] F #F by 3 eigen Matrix of face (triangle) indices
65+
@param[in] PD1 #F by 3 eigen Matrix of the first per face frame field vector
66+
@param[in] PD2 #F by 3 eigen Matrix of the second per face frame field vector
67+
@param[out] BIS1 #F by 3 eigen Matrix of the first per face frame field bisector
68+
@param[out] BIS2 #F by 3 eigen Matrix of the second per face frame field bisector
69+
)"
70+
);
71+
}

src/cross_field_mismatch.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "default_types.h"
2+
#include <igl/cross_field_mismatch.h>
3+
#include <nanobind/nanobind.h>
4+
#include <nanobind/ndarray.h>
5+
#include <nanobind/eigen/dense.h>
6+
#include <nanobind/stl/tuple.h>
7+
8+
namespace nb = nanobind;
9+
using namespace nb::literals;
10+
11+
void bind_cross_field_mismatch(nb::module_ &m)
12+
{
13+
m.def("cross_field_mismatch",
14+
[](
15+
const Eigen::MatrixXN& V,
16+
const Eigen::MatrixXI& F,
17+
const Eigen::MatrixXN& PD1,
18+
const Eigen::MatrixXN& PD2,
19+
const bool isCombed
20+
) {
21+
Eigen::MatrixXI mismatch;
22+
igl::cross_field_mismatch(V, F, PD1, PD2, isCombed, mismatch);
23+
return mismatch;
24+
},
25+
"V"_a,
26+
"F"_a,
27+
"PD1"_a,
28+
"PD2"_a,
29+
"isCombed"_a,
30+
R"(Calculates the mismatch (integer), at each face edge, of a cross field defined on the mesh faces.
31+
The integer mismatch is a multiple of pi/2 that transforms the cross on one side of the edge to
32+
the cross on the other side. It represents the deviation from a Lie connection across the edge.
33+
34+
@param[in] V #V by 3 eigen Matrix of mesh vertex 3D positions
35+
@param[in] F #F by 3 eigen Matrix of face (quad) indices
36+
@param[in] PD1 #F by 3 eigen Matrix of the first per face cross field vector
37+
@param[in] PD2 #F by 3 eigen Matrix of the second per face cross field vector
38+
@param[in] isCombed boolean, specifying whether the field is combed (i.e. matching has been precomputed.
39+
If not, the field is combed first.
40+
@param[out] mismatch #F by 3 eigen Matrix containing the integer mismatch of the cross field
41+
across all face edges
42+
)"
43+
44+
);
45+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include "default_types.h"
2+
#include <igl/find_cross_field_singularities.h>
3+
#include <nanobind/nanobind.h>
4+
#include <nanobind/ndarray.h>
5+
#include <nanobind/eigen/dense.h>
6+
#include <nanobind/stl/tuple.h>
7+
8+
namespace nb = nanobind;
9+
using namespace nb::literals;
10+
11+
void bind_find_cross_field_singularities(nb::module_ &m)
12+
{
13+
m.def("find_cross_field_singularities",
14+
[](
15+
const Eigen::MatrixXN& V,
16+
const Eigen::MatrixXI& F,
17+
const Eigen::MatrixXI& mismatch
18+
) {
19+
Eigen::VectorXI isSingularity, singularityIndex;
20+
igl::find_cross_field_singularities(V, F, mismatch, isSingularity, singularityIndex);
21+
return std::make_tuple(isSingularity, singularityIndex);
22+
},
23+
"V"_a,
24+
"F"_a,
25+
"mismatch"_a,
26+
R"(Computes singularities of a cross field, assumed combed
27+
28+
@param[in] V #V by 3 eigen Matrix of mesh vertex 3D positions
29+
@param[in] F #F by 3 eigen Matrix of face (quad) indices
30+
@param[in] mismatch #F by 3 eigen Matrix containing the integer mismatch of the cross field
31+
across all face edges
32+
@param[out] isSingularity #V by 1 boolean eigen Vector indicating the presence of a singularity on a vertex
33+
@param[out] singularityIndex #V by 1 integer eigen Vector containing the singularity indices
34+
)"
35+
);
36+
37+
// overload
38+
m.def("find_cross_field_singularities",
39+
[](
40+
const Eigen::MatrixXN& V,
41+
const Eigen::MatrixXI& F,
42+
const Eigen::MatrixXN& PD1,
43+
const Eigen::MatrixXN& PD2,
44+
bool isCombed
45+
) {
46+
Eigen::VectorXI isSingularity, singularityIndex;
47+
igl::find_cross_field_singularities(V, F, PD1, PD2, isSingularity, singularityIndex, isCombed);
48+
return std::make_tuple(isSingularity, singularityIndex);
49+
},
50+
"V"_a,
51+
"F"_a,
52+
"PD1"_a,
53+
"PD2"_a,
54+
"isCombed"_a = false,
55+
R"(Wrapper that calculates the mismatch if it is not provided.
56+
57+
@param[in] PD1 #F by 3 eigen Matrix of the first per face cross field vector
58+
@param[in] PD2 #F by 3 eigen Matrix of the second per face cross field vector
59+
@param[in] isCombed boolean indicating whether the cross field is combed
60+
61+
\note the field in PD1 and PD2 MUST BE combed (see igl::comb_cross_field).
62+
)"
63+
);
64+
}

src/rotate_vectors.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "default_types.h"
2+
#include <igl/rotate_vectors.h>
3+
#include <nanobind/eigen/dense.h>
4+
#include <nanobind/nanobind.h>
5+
#include <nanobind/ndarray.h>
6+
#include <nanobind/stl/tuple.h>
7+
8+
namespace nb = nanobind;
9+
using namespace nb::literals;
10+
11+
void bind_rotate_vectors(nb::module_ &m) {
12+
m.def(
13+
"rotate_vectors",
14+
[](const Eigen::MatrixXN &V, const Eigen::VectorXN &A,
15+
const Eigen::MatrixXN &B1, const Eigen::MatrixXN &B2) {
16+
return igl::rotate_vectors(V, A, B1, B2);
17+
},
18+
"V"_a, "A"_a, "B1"_a, "B2"_a,
19+
R"(Rotate the vectors V by A radians on the tangent plane spanned by B1 and B2
20+
21+
@param[in] V #V by 3 eigen Matrix of vectors
22+
@param[in] A #V eigen vector of rotation angles or a single angle to be applied
23+
to all vectors
24+
@param[in] B1 #V by 3 eigen Matrix of base vector 1
25+
@param[in] B2 #V by 3 eigen Matrix of base vector 2
26+
@return the rotated vectors
27+
)");
28+
}

0 commit comments

Comments
 (0)