Added tutorial 609_Boolean and CGAL python module + functions

Former-commit-id: 7b6b91bd7a
This commit is contained in:
Sebastian Koch
2016-06-17 17:25:27 +02:00
parent 39df4de193
commit 9727746942
8 changed files with 312 additions and 2 deletions
+5
View File
@@ -107,6 +107,11 @@ if (LIBIGL_WITH_TRIANGLE)
list(APPEND SHARED_SOURCES "modules/py_igl_triangle.cpp")
endif ()
if (LIBIGL_WITH_CGAL)
add_definitions(-DPY_CGAL)
list(APPEND SHARED_SOURCES "modules/copyleft/py_igl_cgal.cpp")
endif ()
## Prepare the python library
add_library(pyigl SHARED
+18
View File
@@ -0,0 +1,18 @@
//#include <Eigen/Geometry>
//#include <Eigen/Dense>
//#include <Eigen/Sparse>
#include "../../python_shared.h"
#include <igl/copyleft/cgal/mesh_boolean.h>
void python_export_igl_cgal(py::module &me) {
py::module m = me.def_submodule(
"cgal", "Wrappers for libigl functions that use cgal");
#include "../../py_igl/copyleft/cgal/py_mesh_boolean.cpp"
}
@@ -0,0 +1,107 @@
// COMPLETE BINDINGS ========================
m.def("mesh_boolean", []
(
const Eigen::MatrixXd& VA,
const Eigen::MatrixXi& FA,
const Eigen::MatrixXd& VB,
const Eigen::MatrixXi& FB,
igl::MeshBooleanType & type,
Eigen::MatrixXd& VC,
Eigen::MatrixXi& FC,
Eigen::MatrixXi& J
)
{
return igl::copyleft::cgal::mesh_boolean(VA, FA, VB, FB, type, VC, FC, J);
}, __doc_igl_copyleft_cgal_mesh_boolean,
py::arg("VA"), py::arg("FA"), py::arg("VB"), py::arg("FB"), py::arg("type"), py::arg("VC"), py::arg("FC"), py::arg("J"));
m.def("mesh_boolean", []
(
const Eigen::MatrixXd& VA,
const Eigen::MatrixXi& FA,
const Eigen::MatrixXd& VB,
const Eigen::MatrixXi& FB,
const std::string & type_str,
Eigen::MatrixXd& VC,
Eigen::MatrixXi& FC,
Eigen::MatrixXi& J
)
{
return igl::copyleft::cgal::mesh_boolean(VA, FA, VB, FB, type_str, VC, FC, J);
}, __doc_igl_copyleft_cgal_mesh_boolean,
py::arg("VA"), py::arg("FA"), py::arg("VB"), py::arg("FB"), py::arg("type_str"), py::arg("VC"), py::arg("FC"), py::arg("J"));
m.def("mesh_boolean", []
(
const Eigen::MatrixXd& VA,
const Eigen::MatrixXi& FA,
const Eigen::MatrixXd& VB,
const Eigen::MatrixXi& FB,
const igl::MeshBooleanType & type,
Eigen::MatrixXd& VC,
Eigen::MatrixXi& FC
)
{
return igl::copyleft::cgal::mesh_boolean(VA, FA, VB, FB, type, VC, FC);
}, __doc_igl_copyleft_cgal_mesh_boolean,
py::arg("VA"), py::arg("FA"), py::arg("VB"), py::arg("FB"), py::arg("type"), py::arg("VC"), py::arg("FC"));
// INCOMPLETE BINDINGS ========================
//m.def("mesh_boolean", []
//(
// const Eigen::MatrixXd& VA,
// const Eigen::MatrixXd& FA,
// const Eigen::MatrixXd& VB,
// const Eigen::MatrixXd& FB,
// std::function<int (const Eigen::Matrix<int, 1, Eigen::Dynamic>)> & wind_num_op,
// std::function<int (const int, const int)> & keep,
// Eigen::MatrixXd& VC,
// Eigen::MatrixXd& FC,
// Eigen::MatrixXd& J
//)
//{
// return igl::copyleft::cgal::mesh_boolean(VA, FA, VB, FB, wind_num_op, keep, VC, FC, J);
//}, __doc_igl_copyleft_cgal_mesh_boolean,
//py::arg("VA"), py::arg("FA"), py::arg("VB"), py::arg("FB"), py::arg("wind_num_op"), py::arg("keep"), py::arg("VC"), py::arg("FC"), py::arg("J"));
//m.def("mesh_boolean", []
//(
// std::vector<DerivedV> & Vlist,
// std::vector<DerivedF> & Flist,
// std::function<int (const Eigen::Matrix<int, 1, Eigen::Dynamic>)> & wind_num_op,
// std::function<int (const int, const int)> & keep,
// Eigen::MatrixXd& VC,
// Eigen::MatrixXd& FC,
// Eigen::MatrixXd& J
//)
//{
// return igl::copyleft::cgal::mesh_boolean(Vlist, Flist, wind_num_op, keep, VC, FC, J);
//}, __doc_igl_copyleft_cgal_mesh_boolean,
//py::arg("Vlist"), py::arg("Flist"), py::arg("wind_num_op"), py::arg("keep"), py::arg("VC"), py::arg("FC"), py::arg("J"));
//m.def("mesh_boolean", []
//(
// const Eigen::MatrixXd& VV,
// const Eigen::MatrixXd& FF,
// const Eigen::MatrixXd& sizes,
// std::function<int (const Eigen::Matrix<int, 1, Eigen::Dynamic>)> & wind_num_op,
// std::function<int (const int, const int)> & keep,
// Eigen::MatrixXd& VC,
// Eigen::MatrixXd& FC,
// Eigen::MatrixXd& J
//)
//{
// return igl::copyleft::cgal::mesh_boolean(VV, FF, sizes, wind_num_op, keep, VC, FC, J);
//}, __doc_igl_copyleft_cgal_mesh_boolean,
//py::arg("VV"), py::arg("FF"), py::arg("sizes"), py::arg("wind_num_op"), py::arg("keep"), py::arg("VC"), py::arg("FC"), py::arg("J"));
+10
View File
@@ -0,0 +1,10 @@
py::enum_<igl::MeshBooleanType>(m, "MeshBooleanType")
.value("MESH_BOOLEAN_TYPE_UNION", igl::MESH_BOOLEAN_TYPE_UNION)
.value("MESH_BOOLEAN_TYPE_INTERSECT", igl::MESH_BOOLEAN_TYPE_INTERSECT)
.value("MESH_BOOLEAN_TYPE_MINUS", igl::MESH_BOOLEAN_TYPE_MINUS)
.value("MESH_BOOLEAN_TYPE_XOR", igl::MESH_BOOLEAN_TYPE_XOR)
.value("MESH_BOOLEAN_TYPE_RESOLVE", igl::MESH_BOOLEAN_TYPE_RESOLVE)
.value("NUM_MESH_BOOLEAN_TYPES", igl::NUM_MESH_BOOLEAN_TYPES)
.export_values();
+79
View File
@@ -26,6 +26,10 @@ extern void python_export_igl_embree(py::module &);
extern void python_export_igl_triangle(py::module &);
#endif
#ifdef PY_CGAL
extern void python_export_igl_cgal(py::module &);
#endif
PYBIND11_PLUGIN(pyigl) {
py::module m("pyigl", R"pyigldoc(
Python wrappers for libigl
@@ -36,6 +40,77 @@ PYBIND11_PLUGIN(pyigl) {
.. autosummary::
:toctree: _generate
AABB
ARAPEnergyType
MeshBooleanType
SolverStatus
active_set
arap
avg_edge_length
barycenter
barycentric_coordinates
boundary_facets
boundary_loop
cat
colon
comb_cross_field
comb_frame_field
compute_frame_field_bisectors
copyleft_cgal_mesh_boolean
copyleft_comiso_miq
copyleft_comiso_nrosy
copyleft_tetgen_tetrahedralize
cotmatrix
covariance_scatter_matrix
cross_field_missmatch
cut_mesh_from_singularities
doublearea
edge_lengths
eigs
embree_ambient_occlusion
find_cross_field_singularities
fit_rotations
floor
gaussian_curvature
grad
harmonic
invert_diag
jet
local_basis
lscm
map_vertices_to_circle
massmatrix
min_quad_with_fixed
n_polyvector
parula
per_corner_normals
per_edge_normals
per_face_normals
per_vertex_normals
planarize_quad_mesh
point_mesh_squared_distance
polar_svd
principal_curvature
quad_planarity
readDMAT
readMESH
readOBJ
readOFF
read_triangle_mesh
rotate_vectors
setdiff
signed_distance
slice
slice_into
slice_mask
slice_tets
sortrows
triangle_triangulate
unique
unproject_onto_mesh
upsample
writeMESH
writeOBJ
)pyigldoc");
@@ -63,5 +138,9 @@ PYBIND11_PLUGIN(pyigl) {
python_export_igl_triangle(m);
#endif
#ifdef PY_CGAL
python_export_igl_cgal(m);
#endif
return m.ptr();
}
+8
View File
@@ -26,6 +26,10 @@ extern void python_export_igl_embree(py::module &);
extern void python_export_igl_triangle(py::module &);
#endif
#ifdef PY_CGAL
extern void python_export_igl_cgal(py::module &);
#endif
PYBIND11_PLUGIN(pyigl) {
py::module m("pyigl", R"pyigldoc(
Python wrappers for libigl
@@ -66,5 +70,9 @@ PYBIND11_PLUGIN(pyigl) {
python_export_igl_triangle(m);
#endif
#ifdef PY_CGAL
python_export_igl_cgal(m);
#endif
return m.ptr();
}
+84
View File
@@ -0,0 +1,84 @@
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
dependencies = ["cgal", "viewer"]
check_dependencies(dependencies)
boolean_type_names = {igl.MESH_BOOLEAN_TYPE_UNION: "Union", igl.MESH_BOOLEAN_TYPE_INTERSECT: "Intersect", igl.MESH_BOOLEAN_TYPE_MINUS: "Minus", igl.MESH_BOOLEAN_TYPE_XOR: "XOR", igl.MESH_BOOLEAN_TYPE_RESOLVE: "Resolve"}
boolean_types = list(boolean_type_names.keys())
def update(viewer):
print("Calculating A %s B..." % boolean_type_names[boolean_type])
igl.cgal.mesh_boolean(VA, FA, VB, FB, boolean_type, VC, FC, J)
C = igl.eigen.MatrixXd(FC.rows(), 3)
for f in range(C.rows()):
if J[f] < FA.rows():
C.setRow(f, Red)
else:
C.setRow(f, Green)
viewer.data.clear()
viewer.data.set_mesh(VC, FC)
viewer.data.set_colors(C)
print("Done.")
def key_down(viewer, key, modifier):
global boolean_type
# print(boolean_types)
if key == ord('.'):
boolean_type = boolean_types[(boolean_types.index(boolean_type) + 1) % (len(boolean_types))]
elif key == ord(','):
boolean_type = boolean_types[(boolean_types.index(boolean_type) + len(boolean_types) - 1) % len(boolean_types)]
elif key == ord('['):
viewer.core.camera_dnear -= 0.1
elif key == ord(']'):
viewer.core.camera_dnear += 0.1
else:
return False
#igl.cgal.mesh_boolean(VA, FA, VB, FB, boolean_type, VC, FC)
update(viewer)
return False
if __name__ == "__main__":
# Mesh with per-face color
VA = igl.eigen.MatrixXd()
FA = igl.eigen.MatrixXi()
VB = igl.eigen.MatrixXd()
FB = igl.eigen.MatrixXi()
VC = igl.eigen.MatrixXd()
FC = igl.eigen.MatrixXi()
J = igl.eigen.MatrixXi()
Red = igl.eigen.MatrixXd([[1, 0, 0]])
Green = igl.eigen.MatrixXd([[0, 1, 0]])
# Load meshes in OFF format
igl.readOFF(TUTORIAL_SHARED_PATH + "cheburashka.off", VA, FA)
igl.readOFF(TUTORIAL_SHARED_PATH + "decimated-knight.off", VB, FB)
boolean_type = igl.MESH_BOOLEAN_TYPE_UNION
viewer = igl.viewer.Viewer()
update(viewer)
print(
"Usage: Press '.' to switch to next boolean operation type. \nPress ',' to switch to previous boolean operation type. \nPress ']' to push near cutting plane away from camera. \nPress '[' to pull near cutting plane closer to camera. \nHint: investigate _inside_ the model to see orientation changes. \n")
viewer.core.show_lines = True
viewer.callback_key_down = key_down
viewer.core.camera_dnear = 3.9
viewer.launch()