Browse Source

Added tutorial 705

Former-commit-id: ef2d804f840812dedcc279763da9b53477395030
Sebastian Koch 9 years ago
parent
commit
5e56eb4f81

+ 6 - 0
python/CMakeLists.txt

@@ -66,6 +66,7 @@ option(LIBIGL_WITH_PNG              "Use PNG"            ON)
 option(LIBIGL_WITH_TETGEN           "Use Tetgen"         ON)
 option(LIBIGL_WITH_TRIANGLE         "Use Triangle"       ON)
 option(LIBIGL_WITH_XML              "Use XML"            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)
@@ -112,6 +113,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")

+ 18 - 0
python/modules/copyleft/py_igl_copyleft.cpp

@@ -0,0 +1,18 @@
+//#include <Eigen/Geometry>
+//#include <Eigen/Dense>
+//#include <Eigen/Sparse>
+
+
+#include "../../python_shared.h"
+
+#include <igl/copyleft/marching_cubes.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"
+
+}

+ 25 - 0
python/py_doc.cpp

@@ -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,30 @@ 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_tetgen_tetrahedralize = R"igl_Qu8mg5v7(// Mesh the interior of a surface mesh (V,F) using tetgen
       //
       // Inputs:

+ 2 - 0
python/py_doc.h

@@ -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,7 @@ 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_tetgen_tetrahedralize;
 extern const char *__doc_igl_cotmatrix;
 extern const char *__doc_igl_covariance_scatter_matrix;

+ 2 - 0
python/py_igl.cpp

@@ -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>
@@ -86,6 +87,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"

+ 21 - 0
python/py_igl/copyleft/py_marching_cubes.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"));
+

+ 87 - 0
python/py_igl/py_collapse_edge.cpp

@@ -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"));
+

+ 10 - 0
python/python_shared.cpp

@@ -30,6 +30,10 @@ extern void python_export_igl_triangle(py::module &);
 extern void python_export_igl_cgal(py::module &);
 #endif
 
+#ifdef PY_COPYLEFT
+extern void python_export_igl_copyleft(py::module &);
+#endif
+
 #ifdef PY_PNG
 extern void python_export_igl_png(py::module &);
 #endif
@@ -56,6 +60,7 @@ PYBIND11_PLUGIN(pyigl) {
            boundary_facets
            boundary_loop
            cat
+           collapse_edge
            colon
            comb_cross_field
            comb_frame_field
@@ -63,6 +68,7 @@ PYBIND11_PLUGIN(pyigl) {
            copyleft_cgal_mesh_boolean
            copyleft_comiso_miq
            copyleft_comiso_nrosy
+           copyleft_marching_cubes
            copyleft_tetgen_tetrahedralize
            cotmatrix
            covariance_scatter_matrix
@@ -151,6 +157,10 @@ PYBIND11_PLUGIN(pyigl) {
     python_export_igl_cgal(m);
     #endif
 
+    #ifdef PY_COPYLEFT
+    python_export_igl_copyleft(m);
+    #endif
+
     #ifdef PY_PNG
     python_export_igl_png(m);
     #endif

+ 1 - 1
python/scripts/generate_bindings.py

@@ -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

+ 94 - 0
python/tutorial/705_MarchingCubes.py

@@ -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"]
+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()