Merge branch 'python_bindings' of https://github.com/s-koch/libigl

# Conflicts:
#	python/CMakeLists.txt
This commit is contained in:
Daniele Panozzo
2016-07-06 18:19:51 -04:00
26 changed files with 868 additions and 31 deletions
+7
View File
@@ -67,6 +67,8 @@ option(LIBIGL_WITH_TETGEN "Use Tetgen" ON)
option(LIBIGL_WITH_TRIANGLE "Use Triangle" ON)
option(LIBIGL_WITH_XML "Use XML" ON)
option(LIBIGL_WITH_PYTHON "Use Python" ON)
option(LIBIGL_WITH_COPYLEFT "Use Copyleft" ON)
if(LIBIGL_WITH_CGAL) # Do not remove or move this block, cgal strange build system fails without it
find_package(CGAL REQUIRED)
@@ -113,6 +115,11 @@ if (LIBIGL_WITH_CGAL)
list(APPEND SHARED_SOURCES "modules/copyleft/py_igl_cgal.cpp")
endif ()
if (LIBIGL_WITH_COPYLEFT)
add_definitions(-DPY_COPYLEFT)
list(APPEND SHARED_SOURCES "modules/copyleft/py_igl_copyleft.cpp")
endif ()
if (LIBIGL_WITH_PNG)
add_definitions(-DPY_PNG)
list(APPEND SHARED_SOURCES "modules/py_igl_png.cpp")
@@ -0,0 +1,20 @@
//#include <Eigen/Geometry>
//#include <Eigen/Dense>
//#include <Eigen/Sparse>
#include "../../python_shared.h"
#include <igl/copyleft/marching_cubes.h>
#include <igl/copyleft/swept_volume.h>
void python_export_igl_copyleft(py::module &me) {
py::module m = me.def_submodule(
"copyleft", "Wrappers for libigl functions that are copyleft");
#include "../../py_igl/copyleft/py_marching_cubes.cpp"
#include "../../py_igl/copyleft/py_swept_volume.cpp"
}
+2
View File
@@ -6,6 +6,7 @@
#include "../python_shared.h"
#include <igl/embree/ambient_occlusion.h>
#include <igl/embree/reorient_facets_raycast.h>
void python_export_igl_embree(py::module &me) {
@@ -14,5 +15,6 @@ void python_export_igl_embree(py::module &me) {
"embree", "Wrappers for libigl functions that use embree");
#include "../py_igl/embree/py_ambient_occlusion.cpp"
#include "../py_igl/embree/py_reorient_facets_raycast.cpp"
}
+22
View File
@@ -180,6 +180,7 @@ py::class_<Type> bind_eigen_2(py::module &m, const char *name,
.def("rowwiseMean", [](const Type &m) {return Type(m.rowwise().mean());} )
.def("rowwiseNorm", [](const Type &m) {return Type(m.rowwise().norm());} )
.def("rowwiseNormalized", [](const Type &m) {return Type(m.rowwise().normalized());} )
.def("rowwiseReverse", [](const Type &m) {return Type(m.rowwise().reverse());} )
.def("rowwiseMinCoeff", [](const Type &m) {return Type(m.rowwise().minCoeff());} )
.def("rowwiseMaxCoeff", [](const Type &m) {return Type(m.rowwise().maxCoeff());} )
@@ -188,6 +189,8 @@ py::class_<Type> bind_eigen_2(py::module &m, const char *name,
.def("colwiseProd", [](const Type &m) {return Type(m.colwise().prod());} )
.def("colwiseMean", [](const Type &m) {return Type(m.colwise().mean());} )
.def("colwiseNorm", [](const Type &m) {return Type(m.colwise().norm());} )
.def("colwiseNormalized", [](const Type &m) {return Type(m.colwise().normalized());} )
.def("colwiseReverse", [](const Type &m) {return Type(m.colwise().reverse());} )
.def("colwiseMinCoeff", [](const Type &m) {return Type(m.colwise().minCoeff());} )
.def("colwiseMaxCoeff", [](const Type &m) {return Type(m.colwise().maxCoeff());} )
@@ -689,6 +692,25 @@ void python_export_vector(py::module &m) {
.def("solve",[](const Eigen::SimplicialLLT<Eigen::SparseMatrix<double > >& s, const Eigen::MatrixXd& rhs) { return Eigen::MatrixXd(s.solve(rhs)); })
;
py::class_<Eigen::Affine3d > affine3d(me, "Affine3d");
affine3d
.def(py::init<>())
.def("setIdentity",[](Eigen::Affine3d& a){
return a.setIdentity();
})
.def("rotate",[](Eigen::Affine3d& a, double angle, Eigen::MatrixXd axis) {
assert_is_Vector3("axis", axis);
return a.rotate(Eigen::AngleAxisd(angle, Eigen::Vector3d(axis)));
})
.def("translate",[](Eigen::Affine3d& a, Eigen::MatrixXd offset) {
assert_is_Vector3("offset", offset);
return a.translate(Eigen::Vector3d(offset));
})
.def("matrix", [](Eigen::Affine3d& a) -> Eigen::MatrixXd {
return Eigen::MatrixXd(a.matrix());
})
;
/* Bindings for Quaterniond*/
//py::class_<Eigen::Quaterniond > quaterniond(me, "Quaterniond");
//
+124
View File
@@ -112,6 +112,7 @@ const char *__doc_igl_cat = R"igl_Qu8mg5v7(// Perform concatenation of a two mat
// Outputs:
// C output matrix
// )igl_Qu8mg5v7";
const char *__doc_igl_collapse_edge = R"igl_Qu8mg5v7(See collapse_edge for the documentation.)igl_Qu8mg5v7";
const char *__doc_igl_colon = R"igl_Qu8mg5v7(// Colon operator like matlab's colon operator. Enumerats values between low
// and hi with step step.
// Templates:
@@ -219,6 +220,45 @@ const char *__doc_igl_copyleft_comiso_nrosy = R"igl_Qu8mg5v7(// Generate a N-RoS
// Outputs:
// R #F by 3 the representative vectors of the interpolated field
// S #V by 1 the singularity index for each vertex (0 = regular))igl_Qu8mg5v7";
const char *__doc_igl_copyleft_marching_cubes = R"igl_Qu8mg5v7(// marching_cubes( values, points, x_res, y_res, z_res, vertices, faces )
//
// performs marching cubes reconstruction on the grid defined by values, and
// points, and generates vertices and faces
//
// Input:
// values #number_of_grid_points x 1 array -- the scalar values of an
// implicit function defined on the grid points (<0 in the inside of the
// surface, 0 on the border, >0 outside)
// points #number_of_grid_points x 3 array -- 3-D positions of the grid
// points, ordered in x,y,z order:
// points[index] = the point at (x,y,z) where :
// x = (index % (xres -1),
// y = (index / (xres-1)) %(yres-1),
// z = index / (xres -1) / (yres -1) ).
// where x,y,z index x, y, z dimensions
// i.e. index = x + y*xres + z*xres*yres
// xres resolutions of the grid in x dimension
// yres resolutions of the grid in y dimension
// zres resolutions of the grid in z dimension
// Output:
// vertices #V by 3 list of mesh vertex positions
// faces #F by 3 list of mesh triangle indices
//)igl_Qu8mg5v7";
const char *__doc_igl_copyleft_swept_volume = R"igl_Qu8mg5v7(// Compute the surface of the swept volume of a solid object with surface
// (V,F) mesh under going rigid motion.
//
// Inputs:
// V #V by 3 list of mesh positions in reference pose
// F #F by 3 list of mesh indices into V
// transform function handle so that transform(t) returns the rigid
// transformation at time t∈[0,1]
// steps number of time steps: steps=3 --> t∈{0,0.5,1}
// grid_res number of grid cells on the longest side containing the
// motion (isolevel+1 cells will also be added on each side as padding)
// isolevel distance level to be contoured as swept volume
// Outputs:
// SV #SV by 3 list of mesh positions of the swept surface
// SF #SF by 3 list of mesh faces into SV)igl_Qu8mg5v7";
const char *__doc_igl_copyleft_tetgen_tetrahedralize = R"igl_Qu8mg5v7(// Mesh the interior of a surface mesh (V,F) using tetgen
//
// Inputs:
@@ -355,6 +395,23 @@ const char *__doc_igl_embree_ambient_occlusion = R"igl_Qu8mg5v7(// Compute ambie
// S #P list of ambient occlusion values between 1 (fully occluded) and
// 0 (not occluded)
//)igl_Qu8mg5v7";
const char *__doc_igl_embree_reorient_facets_raycast = R"igl_Qu8mg5v7(// Orient each component (identified by C) of a mesh (V,F) using ambient
// occlusion such that the front side is less occluded than back side, as
// described in "A Simple Method for Correcting Facet Orientations in
// Polygon Meshes Based on Ray Casting" [Takayama et al. 2014].
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of triangle indices
// rays_total Total number of rays that will be shot
// rays_minimum Minimum number of rays that each patch should receive
// facet_wise Decision made for each face independently, no use of patches
// (i.e., each face is treated as a patch)
// use_parity Use parity mode
// is_verbose Verbose output to cout
// Outputs:
// I #F list of whether face has been flipped
// C #F list of patch ID (output of bfs_orient > manifold patches))igl_Qu8mg5v7";
const char *__doc_igl_find_cross_field_singularities = R"igl_Qu8mg5v7(// Inputs:
// V #V by 3 eigen Matrix of mesh vertex 3D positions
// F #F by 3 eigen Matrix of face (quad) indices
@@ -402,6 +459,22 @@ const char *__doc_igl_gaussian_curvature = R"igl_Qu8mg5v7(// Compute discrete lo
// Output:
// K #V by 1 eigen Matrix of discrete gaussian curvature values
//)igl_Qu8mg5v7";
const char *__doc_igl_get_seconds = R"igl_Qu8mg5v7(// Return the current time in seconds since program start
//
// Example:
// const auto & tictoc = []()
// {
// static double t_start = igl::get_seconds();
// double diff = igl::get_seconds()-t_start;
// t_start += diff;
// return diff;
// };
// tictoc();
// ... // part 1
// cout<<"part 1: "<<tictoc()<<endl;
// ... // part 2
// cout<<"part 2: "<<tictoc()<<endl;
// ... // etc)igl_Qu8mg5v7";
const char *__doc_igl_grad = R"igl_Qu8mg5v7(// Gradient of a scalar function defined on piecewise linear elements (mesh)
// is constant on each triangle i,j,k:
// grad(Xijk) = (Xj-Xi) * (Vi - Vk)^R90 / 2A + (Xk-Xi) * (Vj - Vi)^R90 / 2A
@@ -421,6 +494,16 @@ const char *__doc_igl_harmonic = R"igl_Qu8mg5v7(// Compute k-harmonic weight fun
// Outputs:
// W #V by #W list of weights
//)igl_Qu8mg5v7";
const char *__doc_igl_hsv_to_rgb = R"igl_Qu8mg5v7(// Convert RGB to HSV
//
// Inputs:
// h hue value (degrees: [0,360])
// s saturation value ([0,1])
// v value value ([0,1])
// Outputs:
// r red value ([0,1])
// g green value ([0,1])
// b blue value ([0,1]))igl_Qu8mg5v7";
const char *__doc_igl_internal_angles = R"igl_Qu8mg5v7(// Compute internal angles for a triangle mesh
//
// Inputs:
@@ -713,6 +796,12 @@ const char *__doc_igl_quad_planarity = R"igl_Qu8mg5v7(// Compute planarity of th
// Output:
// P #F by 1 eigen Matrix of mesh face (quad) planarities
//)igl_Qu8mg5v7";
const char *__doc_igl_randperm = R"igl_Qu8mg5v7(// Like matlab's randperm(n) but minus 1
//
// Inputs:
// n number of elements
// Outputs:
// I n list of rand permutation of 0:n-1)igl_Qu8mg5v7";
const char *__doc_igl_readDMAT = R"igl_Qu8mg5v7(See readDMAT for the documentation.)igl_Qu8mg5v7";
const char *__doc_igl_readMESH = R"igl_Qu8mg5v7(// load a tetrahedral volume mesh from a .mesh file
//
@@ -960,6 +1049,41 @@ const char *__doc_igl_upsample = R"igl_Qu8mg5v7(// Subdivide a mesh without movi
//
// Known issues:
// - assumes (V,F) is edge-manifold.)igl_Qu8mg5v7";
const char *__doc_igl_winding_number = R"igl_Qu8mg5v7(// WINDING_NUMBER Compute the sum of solid angles of a triangle/tetrahedron
// described by points (vectors) V
//
// Templates:
// dim dimension of input
// Inputs:
// V n by 3 list of vertex positions
// F #F by 3 list of triangle indices, minimum index is 0
// O no by 3 list of origin positions
// Outputs:
// S no by 1 list of winding numbers
//
// 3d)igl_Qu8mg5v7";
const char *__doc_igl_winding_number_3 = R"igl_Qu8mg5v7(// Inputs:
// V pointer to array containing #V by 3 vertex positions along rows,
// given in column major order
// n number of mesh vertices
// F pointer to array containing #F by 3 face indices along rows,
// given in column major order
// m number of faces
// O pointer to array containing #O by 3 query positions along rows,
// given in column major order
// no number of origins
// Outputs:
// S no by 1 list of winding numbers)igl_Qu8mg5v7";
const char *__doc_igl_winding_number_2 = R"igl_Qu8mg5v7(//// Only one evaluation origin
//template <typename DerivedF>
//IGL_INLINE void winding_number_3(
// const double * V,
// const int n,
// const DerivedF * F,
// const int m,
// const double * O,
// double * S);
// 2d)igl_Qu8mg5v7";
const char *__doc_igl_writeMESH = R"igl_Qu8mg5v7(// save a tetrahedral volume mesh to a .mesh file
//
// Templates:
+10
View File
@@ -7,6 +7,7 @@ extern const char *__doc_igl_barycentric_coordinates;
extern const char *__doc_igl_boundary_facets;
extern const char *__doc_igl_boundary_loop;
extern const char *__doc_igl_cat;
extern const char *__doc_igl_collapse_edge;
extern const char *__doc_igl_colon;
extern const char *__doc_igl_comb_cross_field;
extern const char *__doc_igl_comb_frame_field;
@@ -14,6 +15,8 @@ extern const char *__doc_igl_compute_frame_field_bisectors;
extern const char *__doc_igl_copyleft_cgal_mesh_boolean;
extern const char *__doc_igl_copyleft_comiso_miq;
extern const char *__doc_igl_copyleft_comiso_nrosy;
extern const char *__doc_igl_copyleft_marching_cubes;
extern const char *__doc_igl_copyleft_swept_volume;
extern const char *__doc_igl_copyleft_tetgen_tetrahedralize;
extern const char *__doc_igl_cotmatrix;
extern const char *__doc_igl_covariance_scatter_matrix;
@@ -25,14 +28,17 @@ extern const char *__doc_igl_doublearea_quad;
extern const char *__doc_igl_edge_lengths;
extern const char *__doc_igl_eigs;
extern const char *__doc_igl_embree_ambient_occlusion;
extern const char *__doc_igl_embree_reorient_facets_raycast;
extern const char *__doc_igl_find_cross_field_singularities;
extern const char *__doc_igl_fit_rotations;
extern const char *__doc_igl_fit_rotations_planar;
extern const char *__doc_igl_fit_rotations_SSE;
extern const char *__doc_igl_floor;
extern const char *__doc_igl_gaussian_curvature;
extern const char *__doc_igl_get_seconds;
extern const char *__doc_igl_grad;
extern const char *__doc_igl_harmonic;
extern const char *__doc_igl_hsv_to_rgb;
extern const char *__doc_igl_internal_angles;
extern const char *__doc_igl_invert_diag;
extern const char *__doc_igl_is_irregular_vertex;
@@ -58,6 +64,7 @@ extern const char *__doc_igl_point_mesh_squared_distance;
extern const char *__doc_igl_polar_svd;
extern const char *__doc_igl_principal_curvature;
extern const char *__doc_igl_quad_planarity;
extern const char *__doc_igl_randperm;
extern const char *__doc_igl_readDMAT;
extern const char *__doc_igl_readMESH;
extern const char *__doc_igl_readOBJ;
@@ -78,5 +85,8 @@ extern const char *__doc_igl_unique;
extern const char *__doc_igl_unique_rows;
extern const char *__doc_igl_unproject_onto_mesh;
extern const char *__doc_igl_upsample;
extern const char *__doc_igl_winding_number;
extern const char *__doc_igl_winding_number_3;
extern const char *__doc_igl_winding_number_2;
extern const char *__doc_igl_writeMESH;
extern const char *__doc_igl_writeOBJ;
+10
View File
@@ -14,6 +14,7 @@
#include <igl/boundary_facets.h>
#include <igl/boundary_loop.h>
#include <igl/cat.h>
#include <igl/collapse_edge.h>
#include <igl/colon.h>
#include <igl/comb_cross_field.h>
#include <igl/comb_frame_field.h>
@@ -29,8 +30,10 @@
#include <igl/fit_rotations.h>
#include <igl/floor.h>
#include <igl/gaussian_curvature.h>
#include <igl/get_seconds.h>
#include <igl/grad.h>
#include <igl/harmonic.h>
#include <igl/hsv_to_rgb.h>
#include <igl/internal_angles.h>
#include <igl/invert_diag.h>
#include <igl/is_irregular_vertex.h>
@@ -51,6 +54,7 @@
#include <igl/polar_svd.h>
#include <igl/principal_curvature.h>
#include <igl/quad_planarity.h>
#include <igl/randperm.h>
#include <igl/readDMAT.h>
#include <igl/readMESH.h>
#include <igl/readOBJ.h>
@@ -67,6 +71,7 @@
#include <igl/unique.h>
#include <igl/unproject_onto_mesh.h>
#include <igl/upsample.h>
#include <igl/winding_number.h>
#include <igl/writeMESH.h>
#include <igl/writeOBJ.h>
@@ -85,6 +90,7 @@ void python_export_igl(py::module &m)
#include "py_igl/py_boundary_facets.cpp"
#include "py_igl/py_boundary_loop.cpp"
#include "py_igl/py_cat.cpp"
#include "py_igl/py_collapse_edge.cpp"
#include "py_igl/py_colon.cpp"
#include "py_igl/py_comb_cross_field.cpp"
#include "py_igl/py_comb_frame_field.cpp"
@@ -100,8 +106,10 @@ void python_export_igl(py::module &m)
#include "py_igl/py_fit_rotations.cpp"
#include "py_igl/py_floor.cpp"
#include "py_igl/py_gaussian_curvature.cpp"
#include "py_igl/py_get_seconds.cpp"
#include "py_igl/py_grad.cpp"
#include "py_igl/py_harmonic.cpp"
#include "py_igl/py_hsv_to_rgb.cpp"
#include "py_igl/py_internal_angles.cpp"
#include "py_igl/py_invert_diag.cpp"
#include "py_igl/py_is_irregular_vertex.cpp"
@@ -122,6 +130,7 @@ void python_export_igl(py::module &m)
#include "py_igl/py_polar_svd.cpp"
#include "py_igl/py_principal_curvature.cpp"
#include "py_igl/py_quad_planarity.cpp"
#include "py_igl/py_randperm.cpp"
#include "py_igl/py_readDMAT.cpp"
#include "py_igl/py_readMESH.cpp"
#include "py_igl/py_readOBJ.cpp"
@@ -138,6 +147,7 @@ void python_export_igl(py::module &m)
#include "py_igl/py_unique.cpp"
#include "py_igl/py_unproject_onto_mesh.cpp"
#include "py_igl/py_upsample.cpp"
#include "py_igl/py_winding_number.cpp"
#include "py_igl/py_writeMESH.cpp"
#include "py_igl/py_writeOBJ.cpp"
@@ -0,0 +1,21 @@
m.def("marching_cubes", []
(
const Eigen::MatrixXd& values,
const Eigen::MatrixXd& points,
const unsigned int x_res,
const unsigned int y_res,
const unsigned int z_res,
Eigen::MatrixXd& vertices,
Eigen::MatrixXi& faces
)
{
assert_is_VectorX("values", values);
Eigen::VectorXd valuesv;
if (values.size() != 0)
valuesv = values;
return igl::copyleft::marching_cubes(valuesv, points, x_res, y_res, z_res, vertices, faces);
}, __doc_igl_copyleft_marching_cubes,
py::arg("values"), py::arg("points"), py::arg("x_res"), py::arg("y_res"), py::arg("z_res"), py::arg("vertices"), py::arg("faces"));
@@ -0,0 +1,19 @@
m.def("swept_volume", []
(
const Eigen::MatrixXd& V,
const Eigen::MatrixXi& F,
const std::function<Eigen::Affine3d (const double)> & transform,
const size_t steps,
const size_t grid_res,
const size_t isolevel,
Eigen::MatrixXd& SV,
Eigen::MatrixXi& SF
)
{
return igl::copyleft::swept_volume(V, F, transform, steps, grid_res, isolevel, SV, SF);
}, __doc_igl_copyleft_swept_volume,
py::arg("V"), py::arg("F"), py::arg("transform"), py::arg("steps"), py::arg("grid_res"), py::arg("isolevel"), py::arg("SV"), py::arg("SF"));
@@ -0,0 +1,37 @@
m.def("reorient_facets_raycast", []
(
const Eigen::MatrixXd& V,
const Eigen::MatrixXi& F,
int rays_total,
int rays_minimum,
bool facet_wise,
bool use_parity,
bool is_verbose,
Eigen::MatrixXi& I,
Eigen::MatrixXi& C
)
{
Eigen::VectorXi Iv;
Eigen::VectorXi Cv;
igl::embree::reorient_facets_raycast(V, F, rays_total, rays_minimum, facet_wise, use_parity, is_verbose, Iv, Cv);
I = Iv;
C = Cv;
}, __doc_igl_embree_reorient_facets_raycast,
py::arg("V"), py::arg("F"), py::arg("rays_total"), py::arg("rays_minimum"), py::arg("facet_wise"), py::arg("use_parity"), py::arg("is_verbose"), py::arg("I"), py::arg("C"));
m.def("reorient_facets_raycast", []
(
const Eigen::MatrixXd& V,
const Eigen::MatrixXi& F,
Eigen::MatrixXi& FF,
Eigen::MatrixXi& I
)
{
Eigen::VectorXi Iv;
igl::embree::reorient_facets_raycast(V, F, FF, Iv);
I = Iv;
}, __doc_igl_embree_reorient_facets_raycast,
py::arg("V"), py::arg("F"), py::arg("FF"), py::arg("I"));
+87
View File
@@ -0,0 +1,87 @@
// COMPLETE BINDINGS ========================
// INCOMPLETE BINDINGS ========================
//m.def("collapse_edge", []
//(
// int e,
// Eigen::RowVectorXd & p,
// Eigen::MatrixXd& V,
// Eigen::MatrixXi& F,
// Eigen::MatrixXi& E,
// Eigen::MatrixXi& EMAP,
// Eigen::MatrixXi& EF,
// Eigen::MatrixXi& EI,
// int & e1,
// int & e2,
// int & f1,
// int & f2
//)
//{
// return igl::collapse_edge(e, p, V, F, E, EMAP, EF, EI, e1, e2, f1, f2);
//}, __doc_igl_collapse_edge,
//py::arg("e"), py::arg("p"), py::arg("V"), py::arg("F"), py::arg("E"), py::arg("EMAP"), py::arg("EF"), py::arg("EI"), py::arg("e1"), py::arg("e2"), py::arg("f1"), py::arg("f2"));
//m.def("collapse_edge", []
//(
// int e,
// Eigen::RowVectorXd & p,
// Eigen::MatrixXd& V,
// Eigen::MatrixXi& F,
// Eigen::MatrixXi& E,
// Eigen::MatrixXi& EMAP,
// Eigen::MatrixXi& EF,
// Eigen::MatrixXi& EI
//)
//{
// return igl::collapse_edge(e, p, V, F, E, EMAP, EF, EI);
//}, __doc_igl_collapse_edge,
//py::arg("e"), py::arg("p"), py::arg("V"), py::arg("F"), py::arg("E"), py::arg("EMAP"), py::arg("EF"), py::arg("EI"));
//m.def("collapse_edge", []
//(
// std::function<void (const int, const Eigen::MatrixXd &, const Eigen::MatrixXi &, const Eigen::MatrixXi &, const Eigen::VectorXi &, const Eigen::MatrixXi &, const Eigen::MatrixXi &, double &, Eigen::RowVectorXd &)> & cost_and_placement,
// Eigen::MatrixXd& V,
// Eigen::MatrixXi& F,
// Eigen::MatrixXi& E,
// Eigen::MatrixXi& EMAP,
// Eigen::MatrixXi& EF,
// Eigen::MatrixXi& EI,
// std::set<std::pair<double, int> > & Q,
// std::vector<std::set<std::pair<double, int> >::iterator> & Qit,
// Eigen::MatrixXd& C
//)
//{
// return igl::collapse_edge(cost_and_placement, V, F, E, EMAP, EF, EI, Q, Qit, C);
//}, __doc_igl_collapse_edge,
//py::arg("cost_and_placement"), py::arg("V"), py::arg("F"), py::arg("E"), py::arg("EMAP"), py::arg("EF"), py::arg("EI"), py::arg("Q"), py::arg("Qit"), py::arg("C"));
//m.def("collapse_edge", []
//(
// std::function<void (const int, const Eigen::MatrixXd &, const Eigen::MatrixXi &, const Eigen::MatrixXi &, const Eigen::VectorXi &, const Eigen::MatrixXi &, const Eigen::MatrixXi &, double &, Eigen::RowVectorXd &)> & cost_and_placement,
// Eigen::MatrixXd& V,
// Eigen::MatrixXi& F,
// Eigen::MatrixXi& E,
// Eigen::MatrixXi& EMAP,
// Eigen::MatrixXi& EF,
// Eigen::MatrixXi& EI,
// std::set<std::pair<double, int> > & Q,
// std::vector<std::set<std::pair<double, int> >::iterator> & Qit,
// Eigen::MatrixXd& C,
// int & e,
// int & e1,
// int & e2,
// int & f1,
// int & f2
//)
//{
// return igl::collapse_edge(cost_and_placement, V, F, E, EMAP, EF, EI, Q, Qit, C, e, e1, e2, f1, f2);
//}, __doc_igl_collapse_edge,
//py::arg("cost_and_placement"), py::arg("V"), py::arg("F"), py::arg("E"), py::arg("EMAP"), py::arg("EF"), py::arg("EI"), py::arg("Q"), py::arg("Qit"), py::arg("C"), py::arg("e"), py::arg("e1"), py::arg("e2"), py::arg("f1"), py::arg("f2"));
+6
View File
@@ -0,0 +1,6 @@
m.def("get_seconds", []
()
{
return igl::get_seconds();
}, __doc_igl_get_seconds);
+44
View File
@@ -0,0 +1,44 @@
// COMPLETE BINDINGS ========================
m.def("hsv_to_rgb", []
(
const Eigen::MatrixXd& H,
Eigen::MatrixXd& R
)
{
return igl::hsv_to_rgb(H, R);
}, __doc_igl_hsv_to_rgb,
py::arg("H"), py::arg("R"));
// INCOMPLETE BINDINGS ========================
//m.def("hsv_to_rgb", []
//(
// T * hsv,
// T * rgb
//)
//{
// return igl::hsv_to_rgb(hsv, rgb);
//}, __doc_igl_hsv_to_rgb,
//py::arg("hsv"), py::arg("rgb"));
//m.def("hsv_to_rgb", []
//(
// T & h,
// T & s,
// T & v,
// T & r,
// T & g,
// T & b
//)
//{
// return igl::hsv_to_rgb(h, s, v, r, g, b);
//}, __doc_igl_hsv_to_rgb,
//py::arg("h"), py::arg("s"), py::arg("v"), py::arg("r"), py::arg("g"), py::arg("b"));
+10
View File
@@ -0,0 +1,10 @@
m.def("randperm", []
(
int n,
Eigen::MatrixXi& I
)
{
return igl::randperm(n, I);
}, __doc_igl_randperm,
py::arg("n"), py::arg("I"));
+4 -4
View File
@@ -6,15 +6,15 @@ m.def("slice_tets", []
Eigen::MatrixXd& U,
Eigen::MatrixXi& G,
Eigen::MatrixXi& J,
Eigen::SparseMatrix<double> & BC
Eigen::SparseMatrix<double>& BC
)
{
assert_is_VectorX("plane", plane);
Eigen::VectorXd pl;
Eigen::VectorXd planev;
if (plane.size() != 0)
pl = plane;
planev = plane;
Eigen::VectorXi Jv;
igl::slice_tets(V, T, pl, U, G, Jv, BC);
igl::slice_tets(V, T, planev, U, G, Jv, BC);
J = Jv;
}, __doc_igl_slice_tets,
py::arg("V"), py::arg("T"), py::arg("plane"), py::arg("U"), py::arg("G"), py::arg("J"), py::arg("BC"));
+18
View File
@@ -0,0 +1,18 @@
// COMPLETE BINDINGS ========================
m.def("winding_number", []
(
const Eigen::MatrixXd& V,
const Eigen::MatrixXi& F,
const Eigen::MatrixXd& O,
Eigen::MatrixXd& W
)
{
Eigen::VectorXd Wv;
igl::winding_number(V, F, O, Wv);
W = Wv;
}, __doc_igl_winding_number,
py::arg("V"), py::arg("F"), py::arg("O"), py::arg("W"));
+16
View File
@@ -34,6 +34,10 @@ extern void python_export_igl_cgal(py::module &);
extern void python_export_igl_png(py::module &);
#endif
#ifdef PY_COPYLEFT
extern void python_export_igl_copyleft(py::module &);
#endif
PYBIND11_PLUGIN(pyigl) {
py::module m("pyigl", R"pyigldoc(
Python wrappers for libigl
@@ -56,6 +60,7 @@ PYBIND11_PLUGIN(pyigl) {
boundary_facets
boundary_loop
cat
collapse_edge
colon
comb_cross_field
comb_frame_field
@@ -63,6 +68,8 @@ PYBIND11_PLUGIN(pyigl) {
copyleft_cgal_mesh_boolean
copyleft_comiso_miq
copyleft_comiso_nrosy
copyleft_marching_cubes
copyleft_swept_volume
copyleft_tetgen_tetrahedralize
cotmatrix
covariance_scatter_matrix
@@ -72,12 +79,15 @@ PYBIND11_PLUGIN(pyigl) {
edge_lengths
eigs
embree_ambient_occlusion
embree_reorient_facets_raycast
find_cross_field_singularities
fit_rotations
floor
gaussian_curvature
get_seconds
grad
harmonic
hsv_to_rgb
internal_angles
invert_diag
is_irregular_vertex
@@ -100,6 +110,7 @@ PYBIND11_PLUGIN(pyigl) {
polar_svd
principal_curvature
quad_planarity
randperm
readDMAT
readMESH
readOBJ
@@ -117,6 +128,7 @@ PYBIND11_PLUGIN(pyigl) {
unique
unproject_onto_mesh
upsample
winding_number
writeMESH
writeOBJ
@@ -154,5 +166,9 @@ PYBIND11_PLUGIN(pyigl) {
python_export_igl_png(m);
#endif
#ifdef PY_COPYLEFT
python_export_igl_copyleft(m);
#endif
return m.ptr();
}
+1 -1
View File
@@ -79,7 +79,7 @@ def map_parameter_types(name, cpp_type, parsed_types, errors, enum_types):
if len(parsed_types) == 0:
errors.append("Empty typechain: %s" % cpp_type)
if cpp_type == "int" or cpp_type == "bool":
if cpp_type == "int" or cpp_type == "bool" or cpp_type == "unsigned int":
return cpp_type, True
else:
return cpp_type, False
+8
View File
@@ -34,6 +34,10 @@ extern void python_export_igl_cgal(py::module &);
extern void python_export_igl_png(py::module &);
#endif
#ifdef PY_COPYLEFT
extern void python_export_igl_copyleft(py::module &);
#endif
PYBIND11_PLUGIN(pyigl) {
py::module m("pyigl", R"pyigldoc(
Python wrappers for libigl
@@ -82,5 +86,9 @@ PYBIND11_PLUGIN(pyigl) {
python_export_igl_png(m);
#endif
#ifdef PY_COPYLEFT
python_export_igl_copyleft(m);
#endif
return m.ptr();
}
+112
View File
@@ -0,0 +1,112 @@
import sys, os
# Add the igl library to the modules search path
sys.path.insert(0, os.getcwd() + "/../")
import pyigl as igl
from shared import TUTORIAL_SHARED_PATH, check_dependencies, print_usage
dependencies = ["viewer"]
check_dependencies(dependencies)
def append_mesh(C_vis, F_vis, V_vis, V, F, color):
F_vis.conservativeResize(F_vis.rows() + F.rows(), 3)
F_vis.setBottomRows(F.rows(), F + V_vis.rows())
V_vis.conservativeResize(V_vis.rows() + V.rows(), 3)
V_vis.setBottomRows(V.rows(), V)
C_vis.conservativeResize(C_vis.rows() + F.rows(), 3)
colorM = igl.eigen.MatrixXd(F.rows(), C_vis.cols())
colorM.rowwiseSet(color)
C_vis.setBottomRows(F.rows(), colorM)
def update(viewer):
global V, F, T, W, slice_z, overlay
plane = igl.eigen.MatrixXd([0, 0, 1, -((1 - slice_z) * V.col(2).minCoeff() + slice_z * V.col(2).maxCoeff())])
V_vis = igl.eigen.MatrixXd()
F_vis = igl.eigen.MatrixXi()
J = igl.eigen.MatrixXi()
bary = igl.eigen.SparseMatrixd()
igl.slice_tets(V, T, plane, V_vis, F_vis, J, bary)
W_vis = igl.eigen.MatrixXd()
igl.slice(W, J, W_vis)
C_vis = igl.eigen.MatrixXd()
igl.parula(W_vis, False, C_vis)
if overlay == 1: # OVERLAY_INPUT
append_mesh(C_vis, F_vis, V_vis, V, F, igl.eigen.MatrixXd([[1., 0.894, 0.227]]))
elif overlay == 2: # OVERLAY_OUTPUT
append_mesh(C_vis, F_vis, V_vis, V, F, igl.eigen.MatrixXd([[0.8, 0.8, 0.8]]))
viewer.data.clear()
viewer.data.set_mesh(V_vis, F_vis)
viewer.data.set_colors(C_vis)
viewer.data.set_face_based(True)
def key_down(viewer, key, modifier):
global overlay, slice_z
if key == ord(' '):
overlay = (overlay + 1) % 3
elif key == ord('.'):
slice_z = min(slice_z + 0.01, 0.99)
elif key == ord(','):
slice_z = max(slice_z - 0.01, 0.01)
update(viewer)
return False
if __name__ == "__main__":
keys = {"space": "toggle showing input mesh, output mesh or slice through tet-mesh of convex hull",
". / ,": "push back/pull forward slicing plane"}
print_usage(keys)
V = igl.eigen.MatrixXd()
BC = igl.eigen.MatrixXd()
W = igl.eigen.MatrixXd()
T = igl.eigen.MatrixXi()
F = igl.eigen.MatrixXi()
G = igl.eigen.MatrixXi()
slice_z = 0.5
overlay = 0
# Load mesh: (V,T) tet-mesh of convex hull, F contains facets of input
# surface mesh _after_ self-intersection resolution
igl.readMESH(TUTORIAL_SHARED_PATH + "big-sigcat.mesh", V, T, F)
# Compute barycenters of all tets
igl.barycenter(V, T, BC)
# Compute generalized winding number at all barycenters
print("Computing winding number over all %i tets..." % T.rows())
igl.winding_number(V, F, BC, W)
# Extract interior tets
Wt = sum(W > 0.5)
CT = igl.eigen.MatrixXi(Wt, 4)
k = 0
for t in range(T.rows()):
if W[t] > 0.5:
CT.setRow(k, T.row(t))
k += 1
# find bounary facets of interior tets
igl.boundary_facets(CT, G)
# boundary_facets seem to be reversed...
G = G.rowwiseReverse()
# normalize
W = (W - W.minCoeff()) / (W.maxCoeff() - W.minCoeff())
# Plot the generated mesh
viewer = igl.viewer.Viewer()
update(viewer)
viewer.callback_key_down = key_down
viewer.launch()
+94
View File
@@ -0,0 +1,94 @@
import sys, os
# Add the igl library to the modules search path
sys.path.insert(0, os.getcwd() + "/../")
import pyigl as igl
from shared import TUTORIAL_SHARED_PATH, check_dependencies, print_usage
dependencies = ["copyleft", "viewer"]
check_dependencies(dependencies)
def key_down(viewer, key, modifier):
if key == ord('1'):
viewer.data.clear()
viewer.data.set_mesh(V, F)
elif key == ord('2'):
viewer.data.clear()
viewer.data.set_mesh(SV, SF)
elif key == ord('3'):
viewer.data.clear()
viewer.data.set_mesh(BV, BF)
return True
if __name__ == "__main__":
keys = {"1": "show original mesh",
"2": "show marching cubes contour of signed distance",
"3": "show marching cubes contour of indicator function"}
print_usage(keys)
V = igl.eigen.MatrixXd()
F = igl.eigen.MatrixXi()
# Read in inputs as double precision floating point meshes
igl.read_triangle_mesh(TUTORIAL_SHARED_PATH + "armadillo.obj", V, F)
# number of vertices on the largest side
s = 50
Vmin = V.colwiseMinCoeff()
Vmax = V.colwiseMaxCoeff()
h = (Vmax - Vmin).maxCoeff() / s
res = (s * ((Vmax - Vmin) / (Vmax - Vmin).maxCoeff())).castint()
def lerp(res, Vmin, Vmax, di, d):
return Vmin[d] + di / (res[d] - 1) * (Vmax[d] - Vmin[d])
# create grid
print("Creating grid...")
GV = igl.eigen.MatrixXd(res[0] * res[1] * res[2], 3)
for zi in range(res[2]):
z = lerp(res, Vmin, Vmax, zi, 2)
for yi in range(res[1]):
y = lerp(res, Vmin, Vmax, yi, 1)
for xi in range(res[0]):
x = lerp(res, Vmin, Vmax, xi, 0)
GV.setRow(xi + res[0] * (yi + res[1] * zi), igl.eigen.MatrixXd([[x, y, z]]))
# compute values
print("Computing distances...")
S = igl.eigen.MatrixXd()
B = igl.eigen.MatrixXd()
I = igl.eigen.MatrixXi()
C = igl.eigen.MatrixXd()
N = igl.eigen.MatrixXd()
igl.signed_distance(GV, V, F, igl.SIGNED_DISTANCE_TYPE_PSEUDONORMAL, S, I, C, N)
# Convert distances to binary inside-outside data --> aliasing artifacts
B = S.copy()
for e in range(B.rows()):
if B[e] > 0:
B[e] = 1
else:
if B[e] < 0:
B[e] = -1
else:
B[e] = 0
print("Marching cubes...")
SV = igl.eigen.MatrixXd()
BV = igl.eigen.MatrixXd()
SF = igl.eigen.MatrixXi()
BF = igl.eigen.MatrixXi()
igl.copyleft.marching_cubes(S, GV, res[0], res[1], res[2], SV, SF)
igl.copyleft.marching_cubes(B, GV, res[0], res[1], res[2], BV, BF)
# Plot the generated mesh
viewer = igl.viewer.Viewer()
viewer.data.set_mesh(SV, SF)
viewer.callback_key_down = key_down
viewer.launch()
+78
View File
@@ -0,0 +1,78 @@
import sys, os
# Add the igl library to the modules search path
sys.path.insert(0, os.getcwd() + "/../")
import pyigl as igl
from shared import TUTORIAL_SHARED_PATH, check_dependencies, print_usage
dependencies = ["embree", "viewer"]
check_dependencies(dependencies)
def key_down(viewer, key, modifier):
global facetwise, is_showing_reoriented, FF
if key == ord('F') or key == ord('f'):
facetwise = (facetwise + 1) % 2
elif key == ord('S') or key == ord('s'):
scramble_colors()
elif key == ord(' '):
is_showing_reoriented = ~is_showing_reoriented
viewer.data.clear()
viewer.data.set_mesh(V, FF[facetwise] if is_showing_reoriented else F)
viewer.data.set_colors(RGBcolors[facetwise])
return True
def scramble_colors():
global C, viewer, RGBcolors
for p in range(2):
R = igl.eigen.MatrixXi()
igl.randperm(C[p].maxCoeff() + 1, R)
C[p] = igl.slice(R, igl.eigen.MatrixXi(C[p]))
HSV = igl.eigen.MatrixXd(C[p].rows(), 3)
HSV.setCol(0, 360.0 * C[p].castdouble() / C[p].maxCoeff())
HSVright = igl.eigen.MatrixXd(HSV.rows(), 2)
HSVright.setConstant(1.0)
HSV.setRightCols(2, HSVright)
igl.hsv_to_rgb(HSV, RGBcolors[p])
viewer.data.set_colors(RGBcolors[facetwise])
if __name__ == "__main__":
keys = {"space": "toggle between original and reoriented faces",
"F,f": "toggle between patchwise and facetwise reorientation",
"S,s": "scramble colors"}
print_usage(keys)
V = igl.eigen.MatrixXd()
F = igl.eigen.MatrixXi()
C = [igl.eigen.MatrixXi(), igl.eigen.MatrixXi()]
RGBcolors = [igl.eigen.MatrixXd(), igl.eigen.MatrixXd()]
FF = [igl.eigen.MatrixXi(), igl.eigen.MatrixXi()]
is_showing_reoriented = False
facetwise = 0
igl.read_triangle_mesh(TUTORIAL_SHARED_PATH + "truck.obj", V, F)
# Compute patches
for p in range(2):
I = igl.eigen.MatrixXi()
igl.embree.reorient_facets_raycast(V, F, F.rows() * 100, 10, p == 1, False, False, I, C[p])
# apply reorientation
FF[p].conservativeResize(F.rows(), F.cols())
for i in range(I.rows()):
if I[i]:
FF[p].setRow(i, F.row(i).rowwiseReverse())
else:
FF[p].setRow(i, F.row(i))
# Plot the generated mesh
viewer = igl.viewer.Viewer()
viewer.data.set_mesh(V, FF[facetwise] if is_showing_reoriented else F)
viewer.data.set_face_based(True)
scramble_colors()
viewer.callback_key_down = key_down
viewer.launch()
+83
View File
@@ -0,0 +1,83 @@
import sys, os
# Add the igl library to the modules search path
from math import pi, cos
sys.path.insert(0, os.getcwd() + "/../")
import pyigl as igl
from shared import TUTORIAL_SHARED_PATH, check_dependencies, print_usage
dependencies = ["copyleft", "viewer"]
check_dependencies(dependencies)
def key_down(viewer, key, modifier):
global show_swept_volume, SV, SF, V, F
if key == ord(' '):
show_swept_volume = not show_swept_volume
viewer.data.clear()
if show_swept_volume:
viewer.data.set_mesh(SV, SF)
viewer.data.uniform_colors(igl.eigen.MatrixXd([0.2, 0.2, 0.2]), igl.eigen.MatrixXd([1.0, 1.0, 1.0]), igl.eigen.MatrixXd([1.0, 1.0, 1.0])) # TODO replace with constants from cpp
else:
viewer.data.set_mesh(V, F)
viewer.core.is_animating = not show_swept_volume
viewer.data.set_face_based(True)
return True
def pre_draw(viewer):
global show_swept_volume, V
if not show_swept_volume:
T = transform(0.25 * igl.get_seconds())
VT = V * T.matrix().block(0, 0, 3, 3).transpose()
trans = T.matrix().block(0, 3, 3, 1).transpose()
Vtrans = igl.eigen.MatrixXd(VT.rows(), VT.cols())
Vtrans.rowwiseSet(trans)
VT += Vtrans
viewer.data.set_vertices(VT)
viewer.data.compute_normals()
return False
# Define a rigid motion
def transform(t):
T = igl.eigen.Affine3d()
T.setIdentity()
T.rotate(t * 2 * pi, igl.eigen.MatrixXd([0, 1, 0]))
T.translate(igl.eigen.MatrixXd([0, 0.125 * cos(2 * pi * t), 0]))
return T
if __name__ == "__main__":
keys = {"space": "toggle between transforming original mesh and swept volume"}
print_usage(keys)
V = igl.eigen.MatrixXd()
SV = igl.eigen.MatrixXd()
VT = igl.eigen.MatrixXd()
F = igl.eigen.MatrixXi()
SF = igl.eigen.MatrixXi()
show_swept_volume = False
grid_size = 50
time_steps = 200
isolevel = 1
igl.read_triangle_mesh(TUTORIAL_SHARED_PATH + "bunny.off", V, F)
print("Computing swept volume...")
igl.copyleft.swept_volume(V, F, transform, time_steps, grid_size, isolevel, SV, SF)
print("...finished.")
# Plot the generated mesh
viewer = igl.viewer.Viewer()
viewer.data.set_mesh(V, F)
viewer.data.set_face_based(True)
viewer.core.is_animating = not show_swept_volume
viewer.callback_pre_draw = pre_draw
viewer.callback_key_down = key_down
viewer.launch()
@@ -5,19 +5,12 @@ sys.path.insert(0, os.getcwd() + "/../")
import pyigl as igl
from shared import TUTORIAL_SHARED_PATH, check_dependencies
from shared import TUTORIAL_SHARED_PATH, check_dependencies, print_usage
dependencies = ["viewer"]
check_dependencies(dependencies)
# Mesh with per-face color
V = igl.eigen.MatrixXd()
F = igl.eigen.MatrixXi()
C = igl.eigen.MatrixXd()
viewer = igl.viewer.Viewer()
def mouse_down(viewer, a, b):
bc = igl.eigen.MatrixXd()
@@ -27,6 +20,7 @@ def mouse_down(viewer, a, b):
hit = igl.unproject_onto_mesh(coord, viewer.core.view * viewer.core.model,
viewer.core.proj, viewer.core.viewport, V, F, fid, bc)
if hit:
# paint hit red
C.setRow(fid[0, 0], igl.eigen.MatrixXd([[1, 0, 0]]))
viewer.data.set_colors(C)
return True
@@ -34,16 +28,25 @@ def mouse_down(viewer, a, b):
return False
print("Usage: [LeftMouseClick] to select a face")
if __name__ == "__main__":
keys = {"click": "Pick face on shape"}
print_usage(keys)
# Load a mesh in OFF format
igl.readOFF(TUTORIAL_SHARED_PATH + "fertility.off", V, F)
# Mesh with per-face color
V = igl.eigen.MatrixXd()
F = igl.eigen.MatrixXi()
C = igl.eigen.MatrixXd()
# Initialize white
C.setConstant(F.rows(), 3, 1.0)
# Load a mesh in OFF format
igl.readOFF(TUTORIAL_SHARED_PATH + "fertility.off", V, F)
viewer.data.set_mesh(V, F)
viewer.data.set_colors(C)
viewer.core.show_lines = False
viewer.callback_mouse_down = mouse_down
viewer.launch()
# Initialize white
C.setConstant(F.rows(), 3, 1.0)
# Show mesh
viewer = igl.viewer.Viewer()
viewer.data.set_mesh(V, F)
viewer.data.set_colors(C)
viewer.core.show_lines = False
viewer.callback_mouse_down = mouse_down
viewer.launch()
+6
View File
@@ -14,3 +14,9 @@ def check_dependencies(deps):
if not all_available:
sys.exit(-1)
def print_usage(key_dict):
print("Usage:")
for k in key_dict.keys():
print("%s : %s" %(k, key_dict[k]))