Merge branch 'python_bindings' of https://github.com/s-koch/libigl
# Conflicts: # python/CMakeLists.txt
This commit is contained in:
@@ -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"
|
||||
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
//
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
m.def("get_seconds", []
|
||||
()
|
||||
{
|
||||
return igl::get_seconds();
|
||||
}, __doc_igl_get_seconds);
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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"));
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Executable
+112
@@ -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()
|
||||
Executable
+94
@@ -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()
|
||||
Executable
+78
@@ -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()
|
||||
Executable
+83
@@ -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()
|
||||
@@ -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]))
|
||||
|
||||
Reference in New Issue
Block a user