diff --git a/include/igl/unique.cpp b/include/igl/unique.cpp index ab97c6d9d..e04de74cf 100644 --- a/include/igl/unique.cpp +++ b/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 -// -// 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 & A, Eigen::PlainObjectBase & C) @@ -123,7 +122,7 @@ IGL_INLINE void igl::unique( // Eigen::PlainObjectBase& IC) // { // using namespace std; -// +// // typedef Eigen::Matrix RowVector; // vector > rows; // rows.resize(A.rows()); @@ -134,12 +133,12 @@ IGL_INLINE void igl::unique( // rows[i] = SortableRow(ri); // } // vector > vC; -// +// // // unique on rows // vector vIA; // vector vIC; // unique(rows,vC,vIA,vIC); -// +// // // Convert to eigen // C.resize(vC.size(),A.cols()); // IA.resize(vIA.size(),1); diff --git a/include/igl/unique.h b/include/igl/unique.h index eb299eb73..046542afc 100644 --- a/include/igl/unique.h +++ b/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 -// -// 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 & IC); template < typename DerivedA, - typename DerivedC, - typename DerivedIA, - typename DerivedIC> + typename DerivedC> IGL_INLINE void unique( const Eigen::PlainObjectBase & A, Eigen::PlainObjectBase & C); @@ -76,5 +74,3 @@ namespace igl #endif #endif - - diff --git a/python/303_LaplaceEquation.py b/python/303_LaplaceEquation.py new file mode 100644 index 000000000..c15f29193 --- /dev/null +++ b/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() diff --git a/python/py_igl.cpp b/python/py_igl.cpp index c16775bd5..fafecc74f 100644 --- a/python/py_igl.cpp +++ b/python/py_igl.cpp @@ -25,6 +25,10 @@ #include #include #include +#include +#include +#include +#include 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" } diff --git a/python/py_igl/py_boundary_facets.cpp b/python/py_igl/py_boundary_facets.cpp new file mode 100644 index 000000000..a628e8760 --- /dev/null +++ b/python/py_igl/py_boundary_facets.cpp @@ -0,0 +1,30 @@ +m.def("boundary_facets", [] +( + const std::vector > & T, + std::vector > & 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")); diff --git a/python/py_igl/py_min_quad_with_fixed.cpp b/python/py_igl/py_min_quad_with_fixed.cpp new file mode 100644 index 000000000..01bdff0f2 --- /dev/null +++ b/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_ > 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& A, + const Eigen::MatrixXi& known, + const Eigen::SparseMatrix& Aeq, + const bool pd, + igl::min_quad_with_fixed_data & 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 & 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 & 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& A, + const Eigen::MatrixXd& B, + const Eigen::MatrixXi& known, + const Eigen::MatrixXd& Y, + const Eigen::SparseMatrix& 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")); diff --git a/python/py_igl/py_setdiff.cpp b/python/py_igl/py_setdiff.cpp new file mode 100644 index 000000000..be873778f --- /dev/null +++ b/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")); diff --git a/python/py_igl/py_unique.cpp b/python/py_igl/py_unique.cpp new file mode 100644 index 000000000..ba39703ef --- /dev/null +++ b/python/py_igl/py_unique.cpp @@ -0,0 +1,116 @@ +m.def("unique", [] +( + const std::vector & A, + std::vector & C, + std::vector & IA, + std::vector & 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 & A, + std::vector & 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 & A, + std::vector & C, + std::vector & IA, + std::vector & 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 & A, + std::vector & 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"));