Browse Source

added 303 LaplaceEquation

Former-commit-id: 6a1cc40e3ca6413612473059115c72056f12be75
Daniele Panozzo 9 years ago
parent
commit
cda229c05b

+ 9 - 10
include/igl/unique.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "unique.h"
 #include "sort.h"
@@ -97,9 +97,8 @@ IGL_INLINE void igl::unique(
 
 template <
   typename DerivedA,
-  typename DerivedC,
-  typename DerivedIA,
-  typename DerivedIC>
+  typename DerivedC
+  >
 IGL_INLINE void igl::unique(
     const Eigen::PlainObjectBase<DerivedA> & A,
     Eigen::PlainObjectBase<DerivedC> & C)
@@ -123,7 +122,7 @@ IGL_INLINE void igl::unique(
 //   Eigen::PlainObjectBase<DerivedIC>& IC)
 // {
 //   using namespace std;
-// 
+//
 //   typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
 //   vector<SortableRow<RowVector> > rows;
 //   rows.resize(A.rows());
@@ -134,12 +133,12 @@ IGL_INLINE void igl::unique(
 //     rows[i] = SortableRow<RowVector>(ri);
 //   }
 //   vector<SortableRow<RowVector> > vC;
-// 
+//
 //   // unique on rows
 //   vector<size_t> vIA;
 //   vector<size_t> vIC;
 //   unique(rows,vC,vIA,vIC);
-// 
+//
 //   // Convert to eigen
 //   C.resize(vC.size(),A.cols());
 //   IA.resize(vIA.size(),1);

+ 5 - 9
include/igl/unique.h

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #ifndef IGL_UNIQUE_H
 #define IGL_UNIQUE_H
@@ -45,9 +45,7 @@ namespace igl
       Eigen::PlainObjectBase<DerivedIC> & IC);
   template <
     typename DerivedA,
-    typename DerivedC,
-    typename DerivedIA,
-    typename DerivedIC>
+    typename DerivedC>
   IGL_INLINE void unique(
       const Eigen::PlainObjectBase<DerivedA> & A,
       Eigen::PlainObjectBase<DerivedC> & C);
@@ -76,5 +74,3 @@ namespace igl
 #endif
 
 #endif
-
-

+ 73 - 0
python/303_LaplaceEquation.py

@@ -0,0 +1,73 @@
+import igl
+
+V = igl.eigen.MatrixXd()
+F = igl.eigen.MatrixXi()
+
+igl.readOFF("../tutorial/shared/camelhead.off",V,F)
+
+# Find boundary edges
+E = igl.eigen.MatrixXi()
+igl.boundary_facets(F,E);
+
+# Find boundary vertices
+b  = igl.eigen.MatrixXi()
+IA = igl.eigen.MatrixXi()
+IC = igl.eigen.MatrixXi()
+
+igl.unique(E,b,IA,IC);
+
+# List of all vertex indices
+vall  = igl.eigen.MatrixXi()
+vin   = igl.eigen.MatrixXi()
+
+igl.coloni(0,V.rows()-1,vall)
+
+# List of interior indices
+igl.setdiff(vall,b,vin,IA)
+
+# Construct and slice up Laplacian
+L = igl.eigen.SparseMatrixd()
+L_in_in = igl.eigen.SparseMatrixd()
+L_in_b = igl.eigen.SparseMatrixd()
+
+igl.cotmatrix(V,F,L)
+igl.slice(L,vin,vin,L_in_in)
+igl.slice(L,vin,b,L_in_b)
+
+# Dirichlet boundary conditions from z-coordinate
+bc = igl.eigen.MatrixXd()
+Z = V.col(2)
+igl.slice(Z,b,bc)
+
+# Solve PDE
+solver = igl.eigen.SimplicialLLTsparse(-L_in_in)
+Z_in = solver.solve(L_in_b*bc)
+
+# slice into solution
+igl.slice_into(Z_in,vin,Z)
+
+# Alternative, short hand
+mqwf = igl.min_quad_with_fixed_data()
+
+# Linear term is 0
+B = igl.eigen.MatrixXd()
+B.setZero(V.rows(),1);
+
+# Empty constraints
+Beq = igl.eigen.MatrixXd()
+Aeq = igl.eigen.SparseMatrixd()
+
+# Our cotmatrix is _negative_ definite, so flip sign
+igl.min_quad_with_fixed_precompute(-L,b,Aeq,True,mqwf)
+igl.min_quad_with_fixed_solve(mqwf,B,bc,Beq,Z)
+
+# Pseudo-color based on solution
+C = igl.eigen.MatrixXd()
+igl.jet(Z,True,C)
+
+# Plot the mesh with pseudocolors
+viewer = igl.viewer.Viewer()
+viewer.data.set_mesh(V, F)
+viewer.core.show_lines = False
+viewer.data.set_colors(C)
+viewer.launch()

+ 8 - 0
python/py_igl.cpp

@@ -25,6 +25,10 @@
 #include <igl/slice_into.h>
 #include <igl/sortrows.h>
 #include <igl/colon.h>
+#include <igl/boundary_facets.h>
+#include <igl/unique.h>
+#include <igl/setdiff.h>
+#include <igl/min_quad_with_fixed.h>
 
 void python_export_igl(py::module &m)
 {
@@ -51,5 +55,9 @@ void python_export_igl(py::module &m)
 #include "py_igl/py_slice_into.cpp"
 #include "py_igl/py_sortrows.cpp"
 #include "py_igl/py_colon.cpp"
+#include "py_igl/py_boundary_facets.cpp"
+#include "py_igl/py_unique.cpp"
+#include "py_igl/py_setdiff.cpp"
+#include "py_igl/py_min_quad_with_fixed.cpp"
 
 }

+ 30 - 0
python/py_igl/py_boundary_facets.cpp

@@ -0,0 +1,30 @@
+m.def("boundary_facets", []
+(
+  const std::vector<std::vector<int> > & T,
+  std::vector<std::vector<int> > & F
+)
+{
+  return igl::boundary_facets(T,F);
+}, __doc_igl_boundary_facets,
+py::arg("T"), py::arg("F"));
+
+m.def("boundary_facets", []
+(
+  const Eigen::MatrixXi& T,
+  Eigen::MatrixXi& F
+)
+{
+  return igl::boundary_facets(T,F);
+}, __doc_igl_boundary_facets,
+py::arg("T"), py::arg("F"));
+
+m.def("boundary_facets", []
+(
+  const Eigen::MatrixXi& T
+)
+{
+  Eigen::MatrixXi F;
+  igl::boundary_facets(T,F);
+  return F;
+}, __doc_igl_boundary_facets,
+py::arg("T"));

+ 62 - 0
python/py_igl/py_min_quad_with_fixed.cpp

@@ -0,0 +1,62 @@
+
+// Wrap the data class, no properties are exposed since it is not necessary
+py::class_<igl::min_quad_with_fixed_data<double> > min_quad_with_fixed_data(m, "min_quad_with_fixed_data");
+
+min_quad_with_fixed_data
+.def(py::init<>());
+
+m.def("min_quad_with_fixed_precompute", []
+(
+  const Eigen::SparseMatrix<double>& A,
+  const Eigen::MatrixXi& known,
+  const Eigen::SparseMatrix<double>& Aeq,
+  const bool pd,
+  igl::min_quad_with_fixed_data<double> & data
+)
+{
+  return igl::min_quad_with_fixed_precompute(A,known,Aeq,pd,data);
+}, __doc_igl_min_quad_with_fixed,
+py::arg("A"), py::arg("known"), py::arg("Aeq"), py::arg("pd"), py::arg("data"));
+
+m.def("min_quad_with_fixed_solve", []
+(
+  const igl::min_quad_with_fixed_data<double> & data,
+  const Eigen::MatrixXd& B,
+  const Eigen::MatrixXd& Y,
+  const Eigen::MatrixXd & Beq,
+  Eigen::MatrixXd& Z,
+  Eigen::MatrixXd& sol
+)
+{
+  return igl::min_quad_with_fixed_solve(data,B,Y,Beq,Z,sol);
+}, __doc_igl_min_quad_with_fixed,
+py::arg("data"), py::arg("B"), py::arg("Y"), py::arg("Beq"), py::arg("Z"), py::arg("sol"));
+
+m.def("min_quad_with_fixed_solve", []
+(
+  const igl::min_quad_with_fixed_data<double> & data,
+  const Eigen::MatrixXd& B,
+  const Eigen::MatrixXd& Y,
+  const Eigen::MatrixXd & Beq,
+  Eigen::MatrixXd& Z
+)
+{
+  return igl::min_quad_with_fixed_solve(data,B,Y,Beq,Z);
+}, __doc_igl_min_quad_with_fixed,
+py::arg("data"), py::arg("B"), py::arg("Y"), py::arg("Beq"), py::arg("Z"));
+
+m.def("min_quad_with_fixed", []
+(
+  const Eigen::SparseMatrix<double>& A,
+  const Eigen::MatrixXd& B,
+  const Eigen::MatrixXi& known,
+  const Eigen::MatrixXd& Y,
+  const Eigen::SparseMatrix<double>& Aeq,
+  const Eigen::MatrixXd& Beq,
+  const bool pd,
+  Eigen::MatrixXd& Z
+)
+{
+  return igl::min_quad_with_fixed(A,B,known,Y,Aeq,Beq,pd,Z);
+}, __doc_igl_min_quad_with_fixed,
+py::arg("A"), py::arg("B"), py::arg("known"), py::arg("Y"), py::arg("Aeq"), py::arg("Beq"), py::arg("pd"), py::arg("Z"));

+ 11 - 0
python/py_igl/py_setdiff.cpp

@@ -0,0 +1,11 @@
+m.def("setdiff", []
+(
+  const Eigen::MatrixXi& A,
+  const Eigen::MatrixXi& B,
+  Eigen::MatrixXi& C,
+  Eigen::MatrixXi& IA
+)
+{
+  return igl::setdiff(A,B,C,IA);
+}, __doc_igl_setdiff,
+py::arg("A"), py::arg("B"), py::arg("C"), py::arg("IA"));

+ 116 - 0
python/py_igl/py_unique.cpp

@@ -0,0 +1,116 @@
+m.def("unique", []
+(
+  const std::vector<double> & A,
+  std::vector<double> & C,
+  std::vector<size_t> & IA,
+  std::vector<size_t> & IC
+)
+{
+  return igl::unique(A,C,IA,IC);
+}, __doc_igl_unique,
+py::arg("A"), py::arg("C"), py::arg("IA"), py::arg("IC"));
+
+m.def("unique", []
+(
+  const std::vector<double> & A,
+  std::vector<double> & C
+)
+{
+  return igl::unique(A,C);
+}, __doc_igl_unique,
+py::arg("A"), py::arg("C"));
+
+m.def("unique", []
+(
+  const Eigen::MatrixXd& A,
+  Eigen::MatrixXd& C,
+  Eigen::MatrixXi& IA,
+  Eigen::MatrixXi& IC
+)
+{
+  return igl::unique(A,C,IA,IC);
+}, __doc_igl_unique,
+py::arg("A"), py::arg("C"), py::arg("IA"), py::arg("IC"));
+
+m.def("unique", []
+(
+  const Eigen::MatrixXd& A,
+  Eigen::MatrixXd& C
+)
+{
+  return igl::unique(A,C);
+}, __doc_igl_unique,
+py::arg("A"), py::arg("C"));
+
+m.def("unique_rows", []
+(
+  const Eigen::MatrixXd& A,
+  Eigen::MatrixXd& C,
+  Eigen::MatrixXi& IA,
+  Eigen::MatrixXi& IC
+)
+{
+  return igl::unique_rows(A,C,IA,IC);
+}, __doc_igl_unique,
+py::arg("A"), py::arg("C"), py::arg("IA"), py::arg("IC"));
+
+
+
+// int
+
+
+m.def("unique", []
+(
+  const std::vector<int> & A,
+  std::vector<int> & C,
+  std::vector<size_t> & IA,
+  std::vector<size_t> & IC
+)
+{
+  return igl::unique(A,C,IA,IC);
+}, __doc_igl_unique,
+py::arg("A"), py::arg("C"), py::arg("IA"), py::arg("IC"));
+
+m.def("unique", []
+(
+  const std::vector<int> & A,
+  std::vector<int> & C
+)
+{
+  return igl::unique(A,C);
+}, __doc_igl_unique,
+py::arg("A"), py::arg("C"));
+
+m.def("unique", []
+(
+  const Eigen::MatrixXi& A,
+  Eigen::MatrixXi& C,
+  Eigen::MatrixXi& IA,
+  Eigen::MatrixXi& IC
+)
+{
+  return igl::unique(A,C,IA,IC);
+}, __doc_igl_unique,
+py::arg("A"), py::arg("C"), py::arg("IA"), py::arg("IC"));
+
+m.def("unique", []
+(
+  const Eigen::MatrixXi& A,
+  Eigen::MatrixXi& C
+)
+{
+  return igl::unique(A,C);
+}, __doc_igl_unique,
+py::arg("A"), py::arg("C"));
+
+m.def("unique_rows", []
+(
+  const Eigen::MatrixXi& A,
+  Eigen::MatrixXi& C,
+  Eigen::MatrixXi& IA,
+  Eigen::MatrixXi& IC
+)
+{
+  return igl::unique_rows(A,C,IA,IC);
+}, __doc_igl_unique,
+py::arg("A"), py::arg("C"), py::arg("IA"), py::arg("IC"));