Browse Source

working on 204, we need to figure out how to deal with the inconsistency between vectors in numpy and eigen before continuing

Former-commit-id: 27330ae3eb4f1836fbec983d71d9b133a6a8dd5d
Daniele Panozzo 9 years ago
parent
commit
aea1fd183f

+ 53 - 0
python/204_Gradient.py

@@ -0,0 +1,53 @@
+import igl
+
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+# Load a mesh in OFF format
+igl.readOFF("../tutorial/shared/cheburashka.off", V, F)
+
+# Read scalar function values from a file, U: #V by 1
+U = igl.eigen.MatrixXd()
+igl.readDMAT("../tutorial/shared/cheburashka-scalar.dmat",U)
+U = U.col(0)
+
+# Compute gradient operator: #F*3 by #V
+G = igl.eigen.SparseMatrixd()
+igl.grad(V,F,G)
+
+
+# Compute gradient of U
+GU = (G*U).MapMatrix(F.rows(),3)
+
+# Compute gradient magnitude
+GU_mag = GU.rowwiseNorm()
+
+
+  # igl::viewer::Viewer viewer;
+  # viewer.data.set_mesh(V, F);
+
+# Compute pseudocolor for original function
+C = igl.eigen.MatrixXd()
+
+igl.jet(U,True,C)
+
+#
+# # Or for gradient magnitude
+# # igl.jet(GU_mag,True,C)
+#
+#   # viewer.data.set_colors(C);
+#
+# # Average edge length divided by average gradient (for scaling)
+# max_size = igl.avg_edge_length(V,F) / GU_mag.mean()
+#
+# # Draw a black segment in direction of gradient at face barycenters
+# BC = igl.eigen.MatrixXd()
+# igl.barycenter(V,F,BC)
+
+  # const RowVector3d black(0,0,0);
+  # viewer.data.add_edges(BC,BC+max_size*GU, black);
+  #
+  # // Hide wireframe
+  # viewer.core.show_lines = false;
+  #
+  # viewer.launch();

+ 8 - 0
python/py_igl.cpp

@@ -15,6 +15,10 @@
 #include <igl/invert_diag.h>
 #include <igl/principal_curvature.h>
 #include <igl/parula.h>
+#include <igl/readDMAT.h>
+#include <igl/grad.h>
+#include <igl/avg_edge_length.h>
+#include <igl/barycenter.h>
 
 void python_export_igl(py::module &m)
 {
@@ -31,5 +35,9 @@ void python_export_igl(py::module &m)
 #include "py_igl/py_invert_diag.cpp"
 #include "py_igl/py_principal_curvature.cpp"
 #include "py_igl/py_parula.cpp"
+#include "py_igl/py_readDMAT.cpp"
+#include "py_igl/py_grad.cpp"
+#include "py_igl/py_avg_edge_length.cpp"
+#include "py_igl/py_barycenter.cpp"
 
 }

+ 9 - 0
python/py_igl/py_avg_edge_length.cpp

@@ -0,0 +1,9 @@
+m.def("avg_edge_length", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F
+)
+{
+  return igl::avg_edge_length(V,F);
+}, __doc_igl_avg_edge_length,
+py::arg("V"), py::arg("F"));

+ 10 - 0
python/py_igl/py_barycenter.cpp

@@ -0,0 +1,10 @@
+m.def("barycenter", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::MatrixXd BC
+)
+{
+  return igl::barycenter(V,F,BC);
+}, __doc_igl_barycenter,
+py::arg("V"), py::arg("F"), py::arg("BC"));

+ 10 - 0
python/py_igl/py_grad.cpp

@@ -0,0 +1,10 @@
+m.def("grad", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::SparseMatrix<double>& G
+)
+{
+  return igl::grad(V,F,G);
+}, __doc_igl_grad,
+py::arg("V"), py::arg("F"), py::arg("G"));

+ 10 - 0
python/py_igl/py_readDMAT.cpp

@@ -0,0 +1,10 @@
+
+m.def("readDMAT", []
+(
+  const std::string str,
+  Eigen::MatrixXd& W
+)
+{
+  return igl::readDMAT(str,W);
+}, __doc_igl_readDMAT,
+py::arg("str"), py::arg("W"));

+ 27 - 6
python/py_vector.cpp

@@ -130,8 +130,8 @@ py::class_<Type> bind_eigen_1(py::module &m, const char *name,
 
         /* Size query functions */
         .def("size", [](const Type &m) { return m.size(); })
-        .def("cols", &Type::cols)
-        .def("rows", &Type::rows)
+        .def("cols", [](const Type &m) { return m.cols(); })
+        .def("rows", [](const Type &m) { return m.rows(); })
 
         /* Initialization */
         .def("setZero", [](Type &m) { m.setZero(); })
@@ -212,7 +212,12 @@ py::class_<Type> bind_eigen_1(py::module &m, const char *name,
         /* Static initializers */
         .def_static("Zero", [](size_t n) { return Type(Type::Zero(n)); })
         .def_static("Ones", [](size_t n) { return Type(Type::Ones(n)); })
-        .def_static("Constant", [](size_t n, Scalar value) { return Type(Type::Constant(n, value)); });
+        .def_static("Constant", [](size_t n, Scalar value) { return Type(Type::Constant(n, value)); })
+        .def("MapMatrix", [](const Type& m, size_t r, size_t c)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(Eigen::Map<const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>>(m.data(),r,c));
+        })
+        ;
     return vector;
 }
 
@@ -258,8 +263,8 @@ py::class_<Type> bind_eigen_2(py::module &m, const char *name,
 
         /* Size query functions */
         .def("size", [](const Type &m) { return m.size(); })
-        .def("cols", &Type::cols)
-        .def("rows", &Type::rows)
+        .def("cols", [](const Type &m) { return m.cols(); })
+        .def("rows", [](const Type &m) { return m.rows(); })
 
         /* Initialization */
         .def("setZero", [](Type &m) { m.setZero(); })
@@ -362,7 +367,12 @@ py::class_<Type> bind_eigen_2(py::module &m, const char *name,
         .def_static("Zero", [](size_t n, size_t m) { return Type(Type::Zero(n, m)); })
         .def_static("Ones", [](size_t n, size_t m) { return Type(Type::Ones(n, m)); })
         .def_static("Constant", [](size_t n, size_t m, Scalar value) { return Type(Type::Constant(n, m, value)); })
-        .def_static("Identity", [](size_t n, size_t m) { return Type(Type::Identity(n, m)); });
+        .def_static("Identity", [](size_t n, size_t m) { return Type(Type::Identity(n, m)); })
+        .def("MapMatrix", [](const Type& m, size_t r, size_t c)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(Eigen::Map<const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>>(m.data(),r,c));
+        })
+        ;
     return matrix;
 }
 
@@ -450,6 +460,17 @@ py::class_<Type> bind_eigen_sparse_2(py::module &m, const char *name,
         {
           return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(b * a);
         })
+        // Special case, sparse * dense vector produces a dense vector
+        .def("__mul__", []
+        (const Type &a, const Eigen::Matrix<Scalar,Eigen::Dynamic,1>& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,1>(a * b);
+        })
+        .def("__rmul__", [](const Type& a, const Eigen::Matrix<Scalar,1,Eigen::Dynamic>& b)
+        {
+          return Eigen::Matrix<Scalar,1,Eigen::Dynamic>(b * a);
+        })
+
         //.def(py::self * Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>())
         .def_cast(py::self / Scalar())