浏览代码

fixed bug in render to tga

Former-commit-id: 34e1c9fedc52a2ed724d6ca8a84315f097f1aeea
jalec 13 年之前
父节点
当前提交
98be5f8569

+ 22 - 0
examples/harwell_boeing/Makefile

@@ -0,0 +1,22 @@
+
+.PHONY: all
+
+all: example
+
+.PHONY: example
+
+igl_lib=../../
+eigen=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported
+
+CFLAGS=-g
+inc=-I$(igl_lib)/include $(eigen)
+lib=-L$(igl_lib)/lib -ligl
+
+example: example.o
+	g++ $(CFLAGS) -o example example.o $(lib)
+
+example.o: example.cpp
+	g++ $(CFLAGS) -c example.cpp -o example.o $(inc)
+clean:
+	rm -f example.o
+	rm -f example

+ 2 - 0
examples/harwell_boeing/README

@@ -0,0 +1,2 @@
+Demonstrates how to use igl/harwell_boeing which computes indices and values of compressed column storage:
+http://eigen.tuxfamily.org/api/classEigen_1_1SparseMatrix.html

+ 44 - 0
examples/harwell_boeing/example.cpp

@@ -0,0 +1,44 @@
+#define IGL_HEADER_ONLY
+#include <igl/harwell_boeing.h>
+
+template <typename T>
+void print(T & v)
+{
+  std::cout<<v<<" ";
+}
+
+#include <cstdio>
+#include <vector>
+#include <algorithm>
+int main(int argc,char * argv[])
+{
+  using namespace Eigen;
+  using namespace std;
+  using namespace igl;
+  SparseMatrix<double> A(5,5);
+  A.insert(0,1) = 3;
+  A.insert(1,0) = 22;
+  A.insert(1,4) = 17;
+  A.insert(2,0) = 7;
+  A.insert(2,1) = 5;
+  A.insert(2,3) = 1;
+  A.insert(4,2) = 14;
+  A.insert(4,4) = 8;
+
+  vector<double> V;
+  vector<int> R,C;
+
+  int nr;
+  harwell_boeing(A,nr,V,R,C);
+  cout<<"V=[";
+  for_each(V.begin(),V.end(),&print<double>);
+  cout<<"];"<<endl;
+  cout<<"R=[";
+  for_each(R.begin(),R.end(),&print<int>);
+  cout<<"];"<<endl;
+  cout<<"C=[";
+  for_each(C.begin(),C.end(),&print<int>);
+  cout<<"];"<<endl;
+
+  return 0;
+}

+ 6 - 0
include/igl/ReAntTweakBar.cpp

@@ -183,6 +183,12 @@ int igl::ReTwBar::TwRefreshBar()
 {
   return ::TwRefreshBar(this->bar);
 }
+
+int igl::ReTwBar::TwTerminate()
+{
+  return ::TwTerminate();
+}
+
 bool igl::ReTwBar::save(const char *file_name)
 {
   FILE * fp;

+ 2 - 0
include/igl/ReAntTweakBar.h

@@ -129,6 +129,7 @@ namespace igl
         unsigned int outValueMaxCount, 
         void *outValues);
       int TwRefreshBar();
+      int TwTerminate();
   
   
     // IO FUNCTIONS
@@ -180,6 +181,7 @@ namespace igl
 //TW_API TwBar *      TW_CALL TwGetBarByIndex(int barIndex);
 //TW_API TwBar *      TW_CALL TwGetBarByName(const char *barName);
 //TW_API int          TW_CALL TwRefreshBar(TwBar *bar);
+//TW_API int          TW_CALL TwTerminate();
 //
 //TW_API int      TW_CALL TwAddVarRW(TwBar *bar, const char *name, TwType type, void *var, const char *def);
 //TW_API int      TW_CALL TwAddVarRO(TwBar *bar, const char *name, TwType type, const void *var, const char *def);

+ 13 - 8
include/igl/find.cpp

@@ -2,17 +2,21 @@
 
 #include "verbose.h"
   
-template <typename T>
+template <
+  typename T, 
+  typename DerivedI, 
+  typename DerivedJ,
+  typename DerivedV>
 IGL_INLINE void igl::find(
   const Eigen::SparseMatrix<T>& X,
-  Eigen::Matrix<int,Eigen::Dynamic,1> & I,
-  Eigen::Matrix<int,Eigen::Dynamic,1> & J,
-  Eigen::Matrix<T,Eigen::Dynamic,1> & V)
+  Eigen::MatrixBase<DerivedI> & I,
+  Eigen::MatrixBase<DerivedJ> & J,
+  Eigen::MatrixBase<DerivedV> & V)
 {
   // Resize outputs to fit nonzeros
-  I.resize(X.nonZeros());
-  J.resize(X.nonZeros());
-  V.resize(X.nonZeros());
+  I.derived().resize(X.nonZeros(),1);
+  J.derived().resize(X.nonZeros(),1);
+  V.derived().resize(X.nonZeros(),1);
 
   int i = 0;
   // Iterate over outside
@@ -52,5 +56,6 @@ IGL_INLINE void igl::find(
 #ifndef IGL_HEADER_ONLY
 // Explicit template specialization
 // generated by autoexplicit.sh
-template void igl::find<double>(Eigen::SparseMatrix<double, 0, int> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&, Eigen::Matrix<int, -1, 1, 0, -1, 1>&, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
+template void igl::find<double, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
+// generated by autoexplicit.sh
 #endif

+ 8 - 4
include/igl/find.h

@@ -18,12 +18,16 @@ namespace igl
   //   J  nnz vector of column indices of non zeros entries in X
   //   V  nnz vector of type T non-zeros entries in X
   //
-  template <typename T>
+  template <
+    typename T, 
+    typename DerivedI, 
+    typename DerivedJ,
+    typename DerivedV>
   IGL_INLINE void find(
     const Eigen::SparseMatrix<T>& X,
-    Eigen::Matrix<int,Eigen::Dynamic,1> & I,
-    Eigen::Matrix<int,Eigen::Dynamic,1> & J,
-    Eigen::Matrix<T,Eigen::Dynamic,1> & V);
+    Eigen::MatrixBase<DerivedI> & I,
+    Eigen::MatrixBase<DerivedJ> & J,
+    Eigen::MatrixBase<DerivedV> & V);
   // Find the non-zero entries and there respective indices in a sparse vector.
   // Similar to matlab's [I,J,V] = find(X), but instead of [I,J] being
   // subscripts into X, since X is a vector we just return I, a list of indices

+ 45 - 0
include/igl/harwell_boeing.cpp

@@ -0,0 +1,45 @@
+#include "harwell_boeing.h"
+
+template <typename Scalar, typename Index>
+IGL_INLINE void igl::harwell_boeing(
+  const Eigen::SparseMatrix<Scalar> & A,
+  int & num_rows,
+  std::vector<Scalar> & V,
+  std::vector<Index> & R,
+  std::vector<Index> & C)
+{
+  num_rows = A.rows();
+  int num_cols = A.cols();
+  int nnz = A.nonZeros();
+  V.resize(nnz);
+  R.resize(nnz);
+  C.resize(num_cols+1);
+
+  // Assumes outersize is columns
+  assert(A.cols() == A.outerSize());
+  int column_pointer = 0;
+  int i = 0;
+  int k = 0;
+  // Iterate over outside
+  for(; k<A.outerSize(); ++k)
+  {
+    C[k] = column_pointer;
+    // Iterate over inside
+    for(typename Eigen::SparseMatrix<Scalar>::InnerIterator it (A,k); it; ++it)
+    {
+      V[i] = it.value();
+      R[i] = it.row();
+      i++;
+      // Also increment column pointer
+      column_pointer++; 
+    }
+  }
+  // by convention C[num_cols] = nnz
+  C[k] = column_pointer;
+}
+
+#ifndef IGL_HEADER_ONLY
+// Explicit template specialization
+// generated by autoexplicit.sh
+template void igl::harwell_boeing<double, int>(Eigen::SparseMatrix<double, 0, int> const&, int&, std::vector<double, std::allocator<double> >&, std::vector<int, std::allocator<int> >&, std::vector<int, std::allocator<int> >&);
+#endif

+ 42 - 0
include/igl/harwell_boeing.h

@@ -0,0 +1,42 @@
+#ifndef IGL_HARWELL_BOEING_H
+#define IGL_HARWELL_BOEING_H
+#include "igl_inline.h"
+
+#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
+#include <Eigen/Sparse>
+#include <vector>
+
+
+namespace igl
+{
+  // Convert the matrix to Compressed sparse column (CSC or CCS) format,
+  // also known as Harwell Boeing format. As described:
+  // http://netlib.org/linalg/html_templates/node92.html
+  // or
+  // http://en.wikipedia.org/wiki/Sparse_matrix
+  //   #Compressed_sparse_column_.28CSC_or_CCS.29
+  // Templates:
+  //   Scalar  type of sparse matrix like double
+  // Inputs:
+  //   A  sparse m by n matrix
+  // Outputs:
+  //   num_rows  number of rows
+  //   V  non-zero values, row indices running fastest, size(V) = nnz 
+  //   R  row indices corresponding to vals, size(R) = nnz
+  //   C  index in vals of first entry in each column, size(C) = num_cols+1
+  //
+  // All indices and pointers are 0-based
+  template <typename Scalar, typename Index>
+  IGL_INLINE void harwell_boeing(
+    const Eigen::SparseMatrix<Scalar> & A,
+    int & num_rows,
+    std::vector<Scalar> & V,
+    std::vector<Index> & R,
+    std::vector<Index> & C);
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "harwell_boeing.cpp"
+#endif
+
+#endif

+ 1 - 0
include/igl/invert_diag.cpp

@@ -36,4 +36,5 @@ IGL_INLINE void igl::invert_diag(
 
 #ifndef IGL_HEADER_ONLY
 // Explicit template specialization
+template void igl::invert_diag<double>(Eigen::SparseMatrix<double, 0, int> const&, Eigen::SparseMatrix<double, 0, int>&);
 #endif

+ 8 - 3
include/igl/launch_medit.cpp

@@ -12,12 +12,17 @@ template <typename DerivedV, typename DerivedT, typename DerivedF>
 IGL_INLINE int igl::launch_medit(
   const Eigen::MatrixBase<DerivedV> & V, 
   const Eigen::MatrixBase<DerivedT> & T,
-  const Eigen::MatrixBase<DerivedF> & F)
+  const Eigen::MatrixBase<DerivedF> & F,
+  const bool wait)
 {
   using namespace std;
   // Build medit command, end with & so command returns without waiting
   stringstream command; 
-  command<<MEDIT_PATH<<" "<<TEMP_MESH_FILE<<" "<<TEMP_MEDIT_FILE<<" &"<<endl;
+  command<<MEDIT_PATH<<" "<<TEMP_MESH_FILE<<" "<<TEMP_MEDIT_FILE;
+  if(!wait)
+  {
+    command<<" &";
+  }
   bool mesh_saved = writeMESH(TEMP_MESH_FILE,V,T,F);
   if(!mesh_saved)
   {
@@ -51,6 +56,6 @@ IGL_INLINE int igl::launch_medit(
 
 #ifndef IGL_HEADER_ONLY
 // Explicit template specialization
-template int igl::launch_medit<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
+template int igl::launch_medit<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, bool);
 #endif
 

+ 5 - 3
include/igl/launch_medit.h

@@ -18,13 +18,15 @@ namespace igl
   //   V  double matrix of vertex positions  #V by 3
   //   T  #T list of tet indices into vertex positions
   //   F  #F list of face indices into vertex positions
-  // Returns returned value of system call (probably not useful because of the
-  //   fork)
+  //   wait  whether to wait for medit process to finish before returning
+  // Returns returned value of system call (probably not useful if wait=false
+  // because of the fork)
   template <typename DerivedV, typename DerivedT, typename DerivedF>
   IGL_INLINE int launch_medit(
     const Eigen::MatrixBase<DerivedV> & V, 
     const Eigen::MatrixBase<DerivedT> & T,
-    const Eigen::MatrixBase<DerivedF> & F);
+    const Eigen::MatrixBase<DerivedF> & F,
+    const bool wait);
 }
 
 #ifdef IGL_HEADER_ONLY

+ 2 - 0
include/igl/list_to_matrix.cpp

@@ -70,6 +70,8 @@ IGL_INLINE bool igl::list_to_matrix(const std::vector<T > & V,Mat & M)
 #ifndef IGL_HEADER_ONLY
 // Explicit template specialization
 // generated by autoexplicit.sh
+template bool igl::list_to_matrix<double, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(std::vector<double, std::allocator<double> > const&, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
+// generated by autoexplicit.sh
 template bool igl::list_to_matrix<int, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 // generated by autoexplicit.sh
 template bool igl::list_to_matrix<double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > >(std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);

+ 35 - 6
include/igl/matrix_to_list.cpp

@@ -2,13 +2,13 @@
 
 #include <Eigen/Dense>
 
-template <typename Mat, typename T>
+template <typename DerivedM>
 IGL_INLINE void igl::matrix_to_list(
-  const Mat & M, 
-  std::vector<std::vector<T > > & V)
+  const Eigen::MatrixBase<DerivedM> & M, 
+  std::vector<std::vector<typename DerivedM::Scalar > > & V)
 {
   using namespace std;
-  V.resize(M.rows(),vector<T >(M.cols()));
+  V.resize(M.rows(),vector<typename DerivedM::Scalar >(M.cols()));
   // loop over rows
   for(int i = 0;i<M.rows();i++)
   {
@@ -20,8 +20,37 @@ IGL_INLINE void igl::matrix_to_list(
   }
 }
 
+template <typename DerivedM>
+IGL_INLINE void igl::matrix_to_list(
+  const Eigen::MatrixBase<DerivedM> & M, 
+  std::vector<typename DerivedM::Scalar > & V)
+{
+  using namespace std;
+  V.resize(M.size());
+  // loop over rows
+  for(int i = 0;i<M.size();i++)
+  {
+    V[i] = M[i];
+  }
+}
+
+template <typename DerivedM>
+IGL_INLINE std::vector<typename DerivedM::Scalar > igl::matrix_to_list(
+    const Eigen::MatrixBase<DerivedM> & M)
+{
+  std::vector<typename DerivedM::Scalar> V;
+  matrix_to_list(M,V);
+  return V;
+}
+
 #ifndef IGL_HEADER_ONLY
 // Explicit template specialization
-template void igl::matrix_to_list<Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >, int>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&);
-template void igl::matrix_to_list<Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >, double>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&);
+// generated by autoexplicit.sh
+template std::vector<Eigen::Matrix<double, -1, 1, 0, -1, 1>::Scalar, std::allocator<Eigen::Matrix<double, -1, 1, 0, -1, 1>::Scalar> > igl::matrix_to_list<Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&);
+// generated by autoexplicit.sh
+template std::vector<Eigen::Matrix<int, -1, 1, 0, -1, 1>::Scalar, std::allocator<Eigen::Matrix<int, -1, 1, 0, -1, 1>::Scalar> > igl::matrix_to_list<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&);
+//template void igl::matrix_to_list<Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >, double>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&);
+//template void igl::matrix_to_list<Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >, int>(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&);
+template void igl::matrix_to_list<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar> >, std::allocator<std::vector<Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar, std::allocator<Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar> > > >&);
+template void igl::matrix_to_list<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, std::allocator<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar> >, std::allocator<std::vector<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, std::allocator<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar> > > >&);
 #endif

+ 14 - 3
include/igl/matrix_to_list.h

@@ -2,6 +2,8 @@
 #define IGL_MATRIX_TO_LIST_H
 #include "igl_inline.h"
 #include <vector>
+#include <Eigen/Dense>
+
 namespace igl
 {
   // Convert a matrix to a list (std::vector) of row vectors of the same size
@@ -16,10 +18,19 @@ namespace igl
   //   M  an m by n matrix
   //
   // See also: list_to_matrix
-  template <typename Mat, typename T>
+  template <typename DerivedM>
+  IGL_INLINE void matrix_to_list(
+    const Eigen::MatrixBase<DerivedM> & M, 
+    std::vector<std::vector<typename DerivedM::Scalar > > & V);
+  // For vector input
+  template <typename DerivedM>
   IGL_INLINE void matrix_to_list(
-    const Mat & M, 
-    std::vector<std::vector<T > > & V);
+    const Eigen::MatrixBase<DerivedM> & M, 
+    std::vector<typename DerivedM::Scalar > & V);
+  // Return wrapper
+  template <typename DerivedM>
+  IGL_INLINE std::vector<typename DerivedM::Scalar > matrix_to_list(
+      const Eigen::MatrixBase<DerivedM> & M);
 }
 
 #ifdef IGL_HEADER_ONLY

+ 5 - 0
include/igl/mosek/Makefile

@@ -2,6 +2,11 @@ include ../../../Makefile.conf
 
 .PHONY: all
 all: libiglmosek
+debug: libiglmosek
+
+include ../../../Makefile.conf
+all: CFLAGS += -O3 -DNDEBUG -j 
+debug: CFLAGS += -g -Wall -Werror
 
 .PHONY: libiglmosek
 libiglmosek: obj ../../../lib/libiglmosek.a

+ 82 - 12
include/igl/mosek/mosek_quadprog.cpp

@@ -1,7 +1,13 @@
 #include "mosek_quadprog.h"
 #include "mosek_guarded.h"
 #include <cstdio>
+#include "../find.h"
 #include "../verbose.h"
+#include "../speye.h"
+#include "../matrix_to_list.h"
+#include "../list_to_matrix.h"
+#include "../harwell_boeing.h"
+#include "../eps.h"
 
 // Little function mosek needs in order to know how to print to std out
 static void MSKAPI printstr(void *handle, char str[])
@@ -12,19 +18,20 @@ static void MSKAPI printstr(void *handle, char str[])
 template <typename Index, typename Scalar>
 IGL_INLINE bool igl::mosek_quadprog(
   const Index n,
-  const std::vector<Index> & Qi,
-  const std::vector<Index> & Qj,
-  const std::vector<Scalar> & Qv,
+  std::vector<Index> & Qi,
+  std::vector<Index> & Qj,
+  std::vector<Scalar> & Qv,
   const std::vector<Scalar> & c,
   const Scalar cf,
   const Index m,
-  const std::vector<Index> & Ari,
+  std::vector<Scalar> & Av,
+  std::vector<Index> & Ari,
   const std::vector<Index> & Acp,
-  const std::vector<Scalar> & Av,
   const std::vector<Scalar> & lc,
   const std::vector<Scalar> & uc,
   const std::vector<Scalar> & lx,
   const std::vector<Scalar> & ux,
+  MosekData & mosek_data,
   std::vector<Scalar> & x)
 {
   // I J V vectors of Q should all be same length
@@ -32,13 +39,13 @@ IGL_INLINE bool igl::mosek_quadprog(
   assert(Qv.size() == Qj.size());
   // number of columns in linear constraint matrix must be ≤ number of
   // variables
-  assert(Acp.size() == (n+1));
+  assert( (int)Acp.size() == (n+1));
   // linear bound vectors must be size of number of constraints or empty
-  assert( (lc.size() == m) || (lc.size() == 0));
-  assert( (uc.size() == m) || (uc.size() == 0));
+  assert( ((int)lc.size() == m) || ((int)lc.size() == 0));
+  assert( ((int)uc.size() == m) || ((int)uc.size() == 0));
   // constant bound vectors must be size of number of variables or empty
-  assert( (lx.size() == n) || (lx.size() == 0));
-  assert( (ux.size() == n) || (ux.size() == 0));
+  assert( ((int)lx.size() == n) || ((int)lx.size() == 0));
+  assert( ((int)ux.size() == n) || ((int)ux.size() == 0));
 
   // allocate space for solution in x
   x.resize(n);
@@ -114,7 +121,7 @@ IGL_INLINE bool igl::mosek_quadprog(
   }
 
   // loop over constraints
-  for(size_t i = 0;i<m;i++)
+  for(int i = 0;i<m;i++)
   {
     // put bounds  on constraints
     mosek_guarded(MSK_putbound(task,MSK_ACC_CON,i,MSK_BK_RA,lc[i],uc[i]));
@@ -221,6 +228,69 @@ IGL_INLINE bool igl::mosek_quadprog(
   return success;
 }
 
+IGL_INLINE bool igl::mosek_quadprog(
+  const Eigen::SparseMatrix<double> & Q,
+  const Eigen::VectorXd & c,
+  const double cf,
+  const Eigen::SparseMatrix<double> & A,
+  const Eigen::VectorXd & lc,
+  const Eigen::VectorXd & uc,
+  const Eigen::VectorXd & lx,
+  const Eigen::VectorXd & ux,
+  MosekData & mosek_data,
+  Eigen::VectorXd & x)
+{
+  using namespace Eigen;
+  using namespace std;
+  using namespace igl;
+
+  // Q should be square
+  assert(Q.rows() == Q.cols());
+  // Q should be symmetric
+  assert( (Q-Q.transpose()).sum() < FLOAT_EPS);
+  // Only keep lower triangular part of Q
+  SparseMatrix<double> QL;
+  //QL = Q.template triangularView<Lower>();
+  QL = Q.triangularView<Lower>();
+  VectorXi Qi,Qj;
+  VectorXd Qv;
+  find(QL,Qi,Qj,Qv);
+  vector<int> vQi = matrix_to_list(Qi);
+  vector<int> vQj = matrix_to_list(Qj);
+  vector<double> vQv = matrix_to_list(Qv);
+
+  // Convert linear term
+  vector<double> vc = matrix_to_list(c);
+
+  assert(lc.size() == A.rows());
+  assert(uc.size() == A.rows());
+  // Convert A to harwell boeing format
+  vector<double> vAv;
+  vector<int> vAr,vAc;
+  int nr;
+  harwell_boeing(A,nr,vAv,vAr,vAc);
+
+  assert(lx.size() == Q.rows());
+  assert(ux.size() == Q.rows());
+  vector<double> vlc = matrix_to_list(lc);
+  vector<double> vuc = matrix_to_list(uc);
+  vector<double> vlx = matrix_to_list(lx);
+  vector<double> vux = matrix_to_list(ux);
+
+  vector<double> vx;
+  bool ret = mosek_quadprog(
+    Q.rows(),vQi,vQj,vQv,
+    vc,
+    cf,
+    nr,
+    vAv, vAr, vAc,
+    vlc,vuc,
+    vlx,vux,
+    mosek_data,
+    vx);
+  list_to_matrix(vx,x);
+  return ret;
+}
 #ifndef IGL_HEADER_ONLY
-// Explicit template specialization
+// Explicit template declarations
 #endif

+ 32 - 6
include/igl/mosek/mosek_quadprog.h

@@ -2,8 +2,17 @@
 #define IGL_MOSEK_QUADPROG_H
 #include "../igl_inline.h"
 #include <vector>
+
+
+#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
+#include <Eigen/Dense>
+#include <Eigen/Sparse>
+
 namespace igl
 {
+  struct MosekData
+  {
+  };
   // Solve a convex quadratic optimization problem with linear and constant
   // bounds, that is:
   //
@@ -45,10 +54,10 @@ namespace igl
   //   m  number of constraints, therefore also number of rows in linear
   //     constraint coefficient matrix A, and in linear constraint bound vectors 
   //     lc and uc
+  //   Av  vector of non-zero values of A, in column compressed order
   //   Ari  vector of row indices corresponding to non-zero values of A,
   //   Acp  vector of indices into Ari and Av of the first entry for each column
   //     of A, size(Acp) = (# columns of A) + 1 = n + 1
-  //   Av  vector of non-zero values of A, in column compressed order
   //   lc  vector of m linear constraint lower bounds
   //   uc  vector of m linear constraint upper bounds
   //   lx  vector of n constant lower bounds
@@ -63,20 +72,37 @@ namespace igl
   template <typename Index, typename Scalar>
   IGL_INLINE bool mosek_quadprog(
     const Index n,
-    const std::vector<Index> & Qi,
-    const std::vector<Index> & Qj,
-    const std::vector<Scalar> & Qv,
+    /* mosek won't allow this to be const*/ std::vector<Index> & Qi,
+    /* mosek won't allow this to be const*/ std::vector<Index> & Qj,
+    /* mosek won't allow this to be const*/ std::vector<Scalar> & Qv,
     const std::vector<Scalar> & c,
     const Scalar cf,
     const Index m,
-    const std::vector<Index> & Ari,
+    /* mosek won't allow this to be const*/ std::vector<Scalar> & Ari,
+    /* mosek won't allow this to be const*/ std::vector<Index> & Ari,
     const std::vector<Index> & Acp,
-    const std::vector<Scalar> & Av,
     const std::vector<Scalar> & lc,
     const std::vector<Scalar> & uc,
     const std::vector<Scalar> & lx,
     const std::vector<Scalar> & ux,
+    MosekData & mosek_data,
     std::vector<Scalar> & x);
+
+  // Wrapper with Eigen elements
+  //// Templates:
+  ////   Scalar  Scalar type for sparse matrix  (e.g. double)
+  ////   Derived  dervied type from matrix/vector (e.g. VectorXd)
+  IGL_INLINE bool mosek_quadprog(
+    const Eigen::SparseMatrix<double> & Q,
+    const Eigen::VectorXd & c,
+    const double cf,
+    const Eigen::SparseMatrix<double> & A,
+    const Eigen::VectorXd & lc,
+    const Eigen::VectorXd & uc,
+    const Eigen::VectorXd & lx,
+    const Eigen::VectorXd & ux,
+    MosekData & mosek_data,
+    Eigen::VectorXd & x);
 }
 
 #ifdef IGL_HEADER_ONLY

+ 6 - 8
include/igl/normalize_row_sums.cpp

@@ -1,9 +1,9 @@
 #include "normalize_row_sums.h"
 
-template <typename DerivedV>
+template <typename DerivedA, typename DerivedB>
 IGL_INLINE void igl::normalize_row_sums(
-  const Eigen::PlainObjectBase<DerivedV>& A,
-  Eigen::PlainObjectBase<DerivedV> & B)
+  const Eigen::MatrixBase<DerivedA>& A,
+  Eigen::MatrixBase<DerivedB> & B)
 {
   // Resize output
   B.derived().resize(A.rows(),A.cols());
@@ -11,15 +11,13 @@ IGL_INLINE void igl::normalize_row_sums(
   // loop over rows
   for(int i = 0; i < A.rows();i++)
   {
-    typename DerivedV::Scalar sum = A.row(i).sum();
+    typename DerivedB::Scalar sum = A.row(i).sum();
     assert(sum != 0);
     B.row(i) = A.row(i).array()/sum;
   }
 }
 #ifndef IGL_HEADER_ONLY
 // Explicit template specialization
-// generated by autoexplicit.sh
-template void igl::normalize_row_sums<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
-template void igl::normalize_row_sums<Eigen::Matrix<double, -1, 3, 1, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&);
-template void igl::normalize_row_sums<Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
+template void igl::normalize_row_sums<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::normalize_row_sums<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
 #endif

+ 3 - 3
include/igl/normalize_row_sums.h

@@ -11,10 +11,10 @@ namespace igl
   //   A  #rows by k input matrix
   // Outputs:
   //   B  #rows by k input matrix, can be the same as A
-  template <typename DerivedV>
+  template <typename DerivedA, typename DerivedB>
   IGL_INLINE void normalize_row_sums(
-   const Eigen::PlainObjectBase<DerivedV>& A,
-   Eigen::PlainObjectBase<DerivedV> & B);
+    const Eigen::MatrixBase<DerivedA>& A,
+    Eigen::MatrixBase<DerivedB> & B);
 }
 
 #ifdef IGL_HEADER_ONLY

+ 3 - 3
include/igl/per_face_normals.h

@@ -12,9 +12,9 @@ namespace igl
   //   N  #F by 3 eigen Matrix of mesh face (triangle) 3D normals
   template <typename DerivedV, typename DerivedF>
   IGL_INLINE void per_face_normals(
-                                     const Eigen::PlainObjectBase<DerivedV>& V,
-                                     const Eigen::PlainObjectBase<DerivedF>& F,
-                                     Eigen::PlainObjectBase<DerivedV> & N);
+    const Eigen::PlainObjectBase<DerivedV>& V,
+    const Eigen::PlainObjectBase<DerivedF>& F,
+    Eigen::PlainObjectBase<DerivedV> & N);
 }
 
 #ifdef IGL_HEADER_ONLY

+ 1 - 1
include/igl/render_to_tga.cpp

@@ -68,5 +68,5 @@ IGL_INLINE bool igl::render_to_tga(
   writeTGA(genericImage,imgFile);
 
   free(genericImage);
-  return true;
+  return fclose(imgFile) == 0;
 }

+ 6 - 0
include/igl/slice_into.cpp

@@ -12,12 +12,15 @@ IGL_INLINE void igl::slice_into(
   int xn = X.cols();
   assert(R.size() == xm);
   assert(C.size() == xn);
+#ifndef NDEBUG
   int ym = Y.size();
   int yn = Y.size();
   assert(R.minCoeff() >= 0);
   assert(R.maxCoeff() < ym);
   assert(C.minCoeff() >= 0);
   assert(C.maxCoeff() < yn);
+#endif
+
   // create temporary dynamic sparse matrix
   Eigen::DynamicSparseMatrix<T, Eigen::RowMajor>  dyn_Y(Y);
   // Iterate over outside
@@ -44,12 +47,14 @@ IGL_INLINE void igl::slice_into(
   int xn = X.cols();
   assert(R.size() == xm);
   assert(C.size() == xn);
+#ifndef NDEBUG
   int ym = Y.size();
   int yn = Y.size();
   assert(R.minCoeff() >= 0);
   assert(R.maxCoeff() < ym);
   assert(C.minCoeff() >= 0);
   assert(C.maxCoeff() < yn);
+#endif
 
   // Build reindexing maps for columns and rows, -1 means not in map
   Eigen::Matrix<int,Eigen::Dynamic,1> RI;
@@ -80,4 +85,5 @@ IGL_INLINE void igl::slice_into(
 // Explicit template specialization
 // generated by autoexplicit.sh
 template void igl::slice_into<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
+template void igl::slice_into<Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
 #endif

+ 1 - 1
matlab-to-eigen.html

@@ -110,7 +110,7 @@
       </tr>
 
       <tr class=d1>
-        <td><pre><code>A(B == 0) = C</code></pre></td>
+        <td><pre><code>A(B == 0) = C(B==0)</code></pre></td>
         <td><pre><code>A = (B == 0).select(C,A)</code></pre></td>
         <td></td>
       </tr>