瀏覽代碼

finished 203, sparse matrix wrapper is still incomplete

Former-commit-id: 27ce402b8fd28d3bb09ea0549d21b35802c6c1f5
Daniele Panozzo 9 年之前
父節點
當前提交
21e2cbf3f9
共有 5 個文件被更改,包括 100 次插入18 次删除
  1. 21 17
      python/203_CurvatureDirections.py
  2. 5 0
      python/py_igl.cpp
  3. 22 0
      python/py_igl/py_parula.cpp
  4. 15 0
      python/py_igl/py_principal_curvature.cpp
  5. 37 1
      python/py_vector.cpp

+ 21 - 17
python/203_CurvatureDirections.py

@@ -17,30 +17,34 @@ igl.massmatrix(V,F,igl.MASSMATRIX_TYPE_VORONOI,M);
 igl.invert_diag(M,Minv);
 
 # Laplace-Beltrami of position
-temp = igl.eigen.SparseMatrixd();
-temp = L*V
 HN = -Minv*(L*V);
 
 # Extract magnitude as mean curvature
-#   VectorXd H = HN.rowwise().norm();
-#
-#   // Compute curvature directions via quadric fitting
-#   MatrixXd PD1,PD2;
-#   VectorXd PV1,PV2;
-#   igl::principal_curvature(V,F,PD1,PD2,PV1,PV2);
-#   // mean curvature
-#   H = 0.5*(PV1+PV2);
-#
+H = HN.rowwiseNorm();
+
+# Compute curvature directions via quadric fitting
+PD1 = igl.eigen.MatrixXd()
+PD2 = igl.eigen.MatrixXd()
+
+PV1 = igl.eigen.VectorXd()
+PV2 = igl.eigen.VectorXd()
+
+igl.principal_curvature(V,F,PD1,PD2,PV1,PV2);
+
+# Mean curvature
+H = 0.5*(PV1+PV2);
+
 #   igl::viewer::Viewer viewer;
 #   viewer.data.set_mesh(V, F);
 #
-#
-#   // Compute pseudocolor
-#   MatrixXd C;
-#   igl::parula(H,true,C);
+
+# Compute pseudocolor
+C = igl.eigen.MatrixXd();
+igl.parula(H,True,C);
+
 #   viewer.data.set_colors(C);
-#
-#   // Average edge length for sizing
+
+# Average edge length for sizing
 #   const double avg = igl::avg_edge_length(V,F);
 #
 #   // Draw a blue segment parallel to the minimal curvature direction

+ 5 - 0
python/py_igl.cpp

@@ -13,6 +13,8 @@
 #include <igl/cotmatrix.h>
 #include <igl/massmatrix.h>
 #include <igl/invert_diag.h>
+#include <igl/principal_curvature.h>
+#include <igl/parula.h>
 
 void python_export_igl(py::module &m)
 {
@@ -27,4 +29,7 @@ void python_export_igl(py::module &m)
 #include "py_igl/py_cotmatrix.cpp"
 #include "py_igl/py_massmatrix.cpp"
 #include "py_igl/py_invert_diag.cpp"
+#include "py_igl/py_principal_curvature.cpp"
+#include "py_igl/py_parula.cpp"
+
 }

+ 22 - 0
python/py_igl/py_parula.cpp

@@ -0,0 +1,22 @@
+m.def("parula", []
+(
+  const Eigen::VectorXd& Z,
+  const bool normalize,
+  Eigen::MatrixXd& C
+)
+{
+  return igl::parula(Z,normalize,C);
+}, __doc_igl_parula,
+py::arg("Z"), py::arg("normalize"), py::arg("C"));
+
+m.def("parula", []
+(
+  const Eigen::VectorXd& Z,
+  const double min_Z,
+  const double max_Z,
+  Eigen::MatrixXd& C
+)
+{
+  return igl::parula(Z,min_Z,max_Z,C);
+}, __doc_igl_parula,
+py::arg("Z"), py::arg("min_Z"), py::arg("max_Z"), py::arg("C"));

+ 15 - 0
python/py_igl/py_principal_curvature.cpp

@@ -0,0 +1,15 @@
+m.def("principal_curvature", []
+(
+  const Eigen::MatrixXd& V,
+  const Eigen::MatrixXi& F,
+  Eigen::MatrixXd& PD1,
+  Eigen::MatrixXd& PD2,
+  Eigen::VectorXd& PV1,
+  Eigen::VectorXd& PV2,
+  unsigned radius,
+  bool useKring
+)
+{
+  return igl::principal_curvature(V,F,PD1,PD2,PV1,PV2,radius,useKring);
+}, __doc_igl_principal_curvature,
+py::arg("V"), py::arg("F"), py::arg("PD1"), py::arg("PD2"), py::arg("PV1"), py::arg("PV2"), py::arg("radius") = 5, py::arg("useKring") = true);

+ 37 - 1
python/py_vector.cpp

@@ -162,6 +162,12 @@ py::class_<Type> bind_eigen_1(py::module &m, const char *name,
         .def_cast(py::self * Scalar())
         .def_cast(py::self / Scalar())
 
+        .def("__rmul__", [](const Type& a, const Scalar& b)
+        {
+          return Type(b * a);
+        })
+
+
         /* Arithmetic in-place operators */
         .def_cast(py::self += py::self)
         .def_cast(py::self -= py::self)
@@ -277,6 +283,21 @@ py::class_<Type> bind_eigen_2(py::module &m, const char *name,
         .def("cwiseProduct", [](const Type &m1, const Type &m2) -> Type { return m1.cwiseProduct(m2); })
         .def("cwiseQuotient", [](const Type &m1, const Type &m2) -> Type { return m1.cwiseQuotient(m2); })
 
+        /* Row and column-wise operations */
+        .def("rowwiseSum", [](const Type &m) {return Type(m.rowwise().sum());} )
+        .def("rowwiseProd", [](const Type &m) {return Type(m.rowwise().prod());} )
+        .def("rowwiseMean", [](const Type &m) {return Type(m.rowwise().mean());} )
+        .def("rowwiseNorm", [](const Type &m) {return Type(m.rowwise().norm());} )
+        .def("rowwiseMinCoeff", [](const Type &m) {return Type(m.rowwise().minCoeff());} )
+        .def("rowwiseMaxCoeff", [](const Type &m) {return Type(m.rowwise().maxCoeff());} )
+
+        .def("colwiseSum", [](const Type &m) {return Type(m.colwise().sum());} )
+        .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("colwiseMinCoeff", [](const Type &m) {return Type(m.colwise().minCoeff());} )
+        .def("colwiseMaxCoeff", [](const Type &m) {return Type(m.colwise().maxCoeff());} )
+
         /* Arithmetic operators (def_cast forcefully casts the result back to a
            Type to avoid type issues with Eigen's crazy expression templates) */
         .def_cast(-py::self)
@@ -286,6 +307,11 @@ py::class_<Type> bind_eigen_2(py::module &m, const char *name,
         .def_cast(py::self * Scalar())
         .def_cast(py::self / Scalar())
 
+        .def("__rmul__", [](const Type& a, const Scalar& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(b * a);
+        })
+
         /* Arithmetic in-place operators */
         .def_cast(py::self += py::self)
         .def_cast(py::self -= py::self)
@@ -414,7 +440,17 @@ py::class_<Type> bind_eigen_sparse_2(py::module &m, const char *name,
         .def_cast(py::self - py::self)
         .def_cast(py::self * py::self)
         .def_cast(py::self * Scalar())
-        .def(py::self * Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>())
+        // Special case, sparse * dense produces a dense matrix
+        .def("__mul__", []
+        (const Type &a, const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(a * b);
+        })
+        .def("__rmul__", [](const Type& a, const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>& b)
+        {
+          return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(b * a);
+        })
+        //.def(py::self * Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>())
         .def_cast(py::self / Scalar())
 
         /* Arithmetic in-place operators */