update bundled_deps

This commit is contained in:
QIDI TECH
2024-11-09 14:05:44 +08:00
parent 17c9bfd127
commit cfc606fea9
1662 changed files with 710 additions and 168 deletions

View File

@@ -0,0 +1,579 @@
// 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
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_MATLAB_MATLAB_WORKSPACE_H
#define IGL_MATLAB_MATLAB_WORKSPACE_H
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <mat.h>
#include <string>
#include <vector>
namespace igl
{
namespace matlab
{
// It would be really great to replicate this for a simple XML-based
// workspace.
//
// Class which contains data of a matlab workspace which can be written to a
// .mat file and loaded from matlab
//
// This depends on matlab at compile time (though it shouldn't necessarily
// have to) but it does not depend on running the matlab engine at run-time.
//
// Known bugs: Treats all matrices as doubles (this may actually be desired
// for some "index" matrices since matlab's sparse command takes doubles
// rather than int class matrices). It is of course not desired when dealing
// with logicals or uint's for images.
class MatlabWorkspace
{
private:
// KNOWN BUG: Why not use a map? Any reason to allow duplicate names?
//
// List of names
std::vector<std::string> names;
// List of data pointers
std::vector<mxArray*> data;
public:
MatlabWorkspace();
~MatlabWorkspace();
// Clear names and data of variables in workspace
inline void clear();
// Save current list of variables
//
// Inputs:
// path path to .mat file
// Returns true on success, false on failure
inline bool write(const std::string & path) const;
// Load list of variables from .mat file
//
// Inputs:
// path path to .mat file
// Returns true on success, false on failure
inline bool read(const std::string & path);
// Assign data to a variable name in the workspace
//
// Template:
// DerivedM eigen matrix (e.g. MatrixXd)
// Inputs:
// M data (usually a matrix)
// name variable name to save into work space
// Returns true on success, false on failure
//
// Known Bugs: Assumes Eigen is using column major ordering
template <typename DerivedM>
inline MatlabWorkspace& save(
const Eigen::PlainObjectBase<DerivedM>& M,
const std::string & name);
// Template:
// MT sparse matrix type (e.g. double)
template <typename MT>
inline MatlabWorkspace& save(
const Eigen::SparseMatrix<MT>& M,
const std::string & name);
// Templates:
// ScalarM scalar type, e.g. double
template <typename ScalarM>
inline MatlabWorkspace& save(
const std::vector<std::vector<ScalarM> > & vM,
const std::string & name);
// Templates:
// ScalarV scalar type, e.g. double
template <typename ScalarV>
inline MatlabWorkspace& save(
const std::vector<ScalarV> & vV,
const std::string & name);
// NOTE: Eigen stores quaternions coefficients as (i,j,k,1), but most of
// our matlab code stores them as (1,i,j,k) This takes a quaternion and
// saves it as a (1,i,j,k) row vector
//
// Templates:
// Q quaternion type
template <typename Q>
inline MatlabWorkspace& save(
const Eigen::Quaternion<Q> & q,
const std::string & name);
inline MatlabWorkspace& save(
const double d,
const std::string & name);
// Same as save() but adds 1 to each element, useful for saving "index"
// matrices like lists of faces or elements
template <typename DerivedM>
inline MatlabWorkspace& save_index(
const Eigen::DenseBase<DerivedM>& M,
const std::string & name);
template <typename ScalarM>
inline MatlabWorkspace& save_index(
const std::vector<std::vector<ScalarM> > & vM,
const std::string & name);
template <typename ScalarV>
inline MatlabWorkspace& save_index(
const std::vector<ScalarV> & vV,
const std::string & name);
// Find a certain matrix by name.
//
// KNOWN BUG: Outputs the first found (not necessarily unique lists).
//
// Template:
// DerivedM eigen matrix (e.g. MatrixXd)
// Inputs:
// name exact name of matrix as string
// Outputs:
// M matrix
// Returns true only if found.
template <typename DerivedM>
inline bool find(
const std::string & name,
Eigen::PlainObjectBase<DerivedM>& M);
template <typename MT>
inline bool find(
const std::string & name,
Eigen::SparseMatrix<MT>& M);
inline bool find(
const std::string & name,
double & d);
inline bool find(
const std::string & name,
int & v);
// Subtracts 1 from all entries
template <typename DerivedM>
inline bool find_index(
const std::string & name,
Eigen::PlainObjectBase<DerivedM>& M);
};
}
}
// Implementation
// Be sure that this is not compiled into libigl.a
// http://stackoverflow.com/a/3318993/148668
// IGL
#include "igl/list_to_matrix.h"
// MATLAB
#include "mat.h"
// STL
#include <iostream>
#include <algorithm>
#include <vector>
inline igl::matlab::MatlabWorkspace::MatlabWorkspace():
names(),
data()
{
}
inline igl::matlab::MatlabWorkspace::~MatlabWorkspace()
{
// clean up data
clear();
}
inline void igl::matlab::MatlabWorkspace::clear()
{
for_each(data.begin(),data.end(),&mxDestroyArray);
data.clear();
names.clear();
}
inline bool igl::matlab::MatlabWorkspace::write(const std::string & path) const
{
using namespace std;
MATFile * mat_file = matOpen(path.c_str(), "w");
if(mat_file == NULL)
{
fprintf(stderr,"Error opening file %s\n",path.c_str());
return false;
}
assert(names.size() == data.size());
// loop over names and data
for(int i = 0;i < (int)names.size(); i++)
{
// Put variable as LOCAL variable
int status = matPutVariable(mat_file,names[i].c_str(), data[i]);
if(status != 0)
{
cerr<<"^MatlabWorkspace::save Error: matPutVariable ("<<names[i]<<
") failed"<<endl;
return false;
}
}
if(matClose(mat_file) != 0)
{
fprintf(stderr,"Error closing file %s\n",path.c_str());
return false;
}
return true;
}
inline bool igl::matlab::MatlabWorkspace::read(const std::string & path)
{
using namespace std;
MATFile * mat_file;
mat_file = matOpen(path.c_str(), "r");
if (mat_file == NULL)
{
cerr<<"Error: failed to open "<<path<<endl;
return false;
}
int ndir;
const char ** dir = (const char **)matGetDir(mat_file, &ndir);
if (dir == NULL) {
cerr<<"Error reading directory of file "<< path<<endl;
return false;
}
mxFree(dir);
// Must close and reopen
if(matClose(mat_file) != 0)
{
cerr<<"Error: failed to close file "<<path<<endl;
return false;
}
mat_file = matOpen(path.c_str(), "r");
if (mat_file == NULL)
{
cerr<<"Error: failed to open "<<path<<endl;
return false;
}
/* Read in each array. */
for (int i=0; i<ndir; i++)
{
const char * name;
mxArray * mx_data = matGetNextVariable(mat_file, &name);
if (mx_data == NULL)
{
cerr<<"Error: matGetNextVariable failed in "<<path<<endl;
return false;
}
const int dims = mxGetNumberOfDimensions(mx_data);
assert(dims == 2);
if(dims != 2)
{
fprintf(stderr,"Variable '%s' has %d ≠ 2 dimensions. Skipping\n",
name,dims);
mxDestroyArray(mx_data);
continue;
}
// don't destroy
names.push_back(name);
data.push_back(mx_data);
}
if(matClose(mat_file) != 0)
{
cerr<<"Error: failed to close file "<<path<<endl;
return false;
}
return true;
}
// Treat everything as a double
template <typename DerivedM>
inline igl::matlab::MatlabWorkspace& igl::matlab::MatlabWorkspace::save(
const Eigen::PlainObjectBase<DerivedM>& M,
const std::string & name)
{
using namespace std;
const int m = M.rows();
const int n = M.cols();
mxArray * mx_data = mxCreateDoubleMatrix(m,n,mxREAL);
data.push_back(mx_data);
names.push_back(name);
// Copy data immediately
// Use Eigen's map and cast to copy
Eigen::Map< Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> >
map(mxGetPr(mx_data),m,n);
map = M.template cast<double>();
return *this;
}
// Treat everything as a double
template <typename MT>
inline igl::matlab::MatlabWorkspace& igl::matlab::MatlabWorkspace::save(
const Eigen::SparseMatrix<MT>& M,
const std::string & name)
{
using namespace std;
const int m = M.rows();
const int n = M.cols();
// THIS WILL NOT WORK FOR ROW-MAJOR
assert(n==M.outerSize());
const int nzmax = M.nonZeros();
mxArray * mx_data = mxCreateSparse(m, n, nzmax, mxREAL);
data.push_back(mx_data);
names.push_back(name);
// Copy data immediately
double * pr = mxGetPr(mx_data);
mwIndex * ir = mxGetIr(mx_data);
mwIndex * jc = mxGetJc(mx_data);
// Iterate over outside
int k = 0;
for(int j=0; j<M.outerSize();j++)
{
jc[j] = k;
// Iterate over inside
for(typename Eigen::SparseMatrix<MT>::InnerIterator it (M,j); it; ++it)
{
pr[k] = it.value();
ir[k] = it.row();
k++;
}
}
jc[M.outerSize()] = k;
return *this;
}
template <typename ScalarM>
inline igl::matlab::MatlabWorkspace& igl::matlab::MatlabWorkspace::save(
const std::vector<std::vector<ScalarM> > & vM,
const std::string & name)
{
Eigen::MatrixXd M;
list_to_matrix(vM,M);
return this->save(M,name);
}
template <typename ScalarV>
inline igl::matlab::MatlabWorkspace& igl::matlab::MatlabWorkspace::save(
const std::vector<ScalarV> & vV,
const std::string & name)
{
Eigen::MatrixXd V;
list_to_matrix(vV,V);
return this->save(V,name);
}
template <typename Q>
inline igl::matlab::MatlabWorkspace& igl::matlab::MatlabWorkspace::save(
const Eigen::Quaternion<Q> & q,
const std::string & name)
{
Eigen::Matrix<Q,1,4> qm;
qm(0,0) = q.w();
qm(0,1) = q.x();
qm(0,2) = q.y();
qm(0,3) = q.z();
return save(qm,name);
}
inline igl::matlab::MatlabWorkspace& igl::matlab::MatlabWorkspace::save(
const double d,
const std::string & name)
{
Eigen::VectorXd v(1);
v(0) = d;
return save(v,name);
}
template <typename DerivedM>
inline igl::matlab::MatlabWorkspace&
igl::matlab::MatlabWorkspace::save_index(
const Eigen::DenseBase<DerivedM>& M,
const std::string & name)
{
DerivedM Mp1 = M;
Mp1.array() += 1;
return this->save(Mp1,name);
}
template <typename ScalarM>
inline igl::matlab::MatlabWorkspace& igl::matlab::MatlabWorkspace::save_index(
const std::vector<std::vector<ScalarM> > & vM,
const std::string & name)
{
Eigen::MatrixXd M;
list_to_matrix(vM,M);
return this->save_index(M,name);
}
template <typename ScalarV>
inline igl::matlab::MatlabWorkspace& igl::matlab::MatlabWorkspace::save_index(
const std::vector<ScalarV> & vV,
const std::string & name)
{
Eigen::MatrixXd V;
list_to_matrix(vV,V);
return this->save_index(V,name);
}
template <typename DerivedM>
inline bool igl::matlab::MatlabWorkspace::find(
const std::string & name,
Eigen::PlainObjectBase<DerivedM>& M)
{
using namespace std;
const int i = std::find(names.begin(), names.end(), name)-names.begin();
if(i>=(int)names.size())
{
return false;
}
assert(i<=(int)data.size());
mxArray * mx_data = data[i];
assert(!mxIsSparse(mx_data));
assert(mxGetNumberOfDimensions(mx_data) == 2);
//cout<<name<<": "<<mxGetM(mx_data)<<" "<<mxGetN(mx_data)<<endl;
const int m = mxGetM(mx_data);
const int n = mxGetN(mx_data);
// Handle vectors: in the sense that anything found becomes a column vector,
// whether it was column vector, row vector or matrix
if(DerivedM::IsVectorAtCompileTime)
{
assert(m==1 || n==1 || (m==0 && n==0));
M.resize(m*n,1);
}else
{
M.resize(m,n);
}
assert(mxGetNumberOfElements(mx_data) == M.size());
// Use Eigen's map and cast to copy
M = Eigen::Map< Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> >
(mxGetPr(mx_data),M.rows(),M.cols()).cast<typename DerivedM::Scalar>();
return true;
}
template <typename MT>
inline bool igl::matlab::MatlabWorkspace::find(
const std::string & name,
Eigen::SparseMatrix<MT>& M)
{
using namespace std;
using namespace Eigen;
const int i = std::find(names.begin(), names.end(), name)-names.begin();
if(i>=(int)names.size())
{
return false;
}
assert(i<=(int)data.size());
mxArray * mx_data = data[i];
// Handle boring case where matrix is actually an empty dense matrix
if(mxGetNumberOfElements(mx_data) == 0)
{
M.resize(0,0);
return true;
}
assert(mxIsSparse(mx_data));
assert(mxGetNumberOfDimensions(mx_data) == 2);
//cout<<name<<": "<<mxGetM(mx_data)<<" "<<mxGetN(mx_data)<<endl;
const int m = mxGetM(mx_data);
const int n = mxGetN(mx_data);
// TODO: It should be possible to directly load the data into the sparse
// matrix without going through the triplets
// Copy data immediately
double * pr = mxGetPr(mx_data);
mwIndex * ir = mxGetIr(mx_data);
mwIndex * jc = mxGetJc(mx_data);
vector<Triplet<MT> > MIJV;
const int nnz = mxGetNzmax(mx_data);
MIJV.reserve(nnz);
// Iterate over outside
int k = 0;
for(int j=0; j<n;j++)
{
// Iterate over inside
while(k<(int)jc[j+1])
{
//cout<<ir[k]<<" "<<j<<" "<<pr[k]<<endl;
assert((int)ir[k]<m);
assert((int)j<n);
MIJV.push_back(Triplet<MT >(ir[k],j,pr[k]));
k++;
}
}
M.resize(m,n);
M.setFromTriplets(MIJV.begin(),MIJV.end());
return true;
}
inline bool igl::matlab::MatlabWorkspace::find(
const std::string & name,
int & v)
{
using namespace std;
const int i = std::find(names.begin(), names.end(), name)-names.begin();
if(i>=(int)names.size())
{
return false;
}
assert(i<=(int)data.size());
mxArray * mx_data = data[i];
assert(!mxIsSparse(mx_data));
assert(mxGetNumberOfDimensions(mx_data) == 2);
//cout<<name<<": "<<mxGetM(mx_data)<<" "<<mxGetN(mx_data)<<endl;
assert(mxGetNumberOfElements(mx_data) == 1);
copy(
mxGetPr(mx_data),
mxGetPr(mx_data)+mxGetNumberOfElements(mx_data),
&v);
return true;
}
inline bool igl::matlab::MatlabWorkspace::find(
const std::string & name,
double & d)
{
using namespace std;
const int i = std::find(names.begin(), names.end(), name)-names.begin();
if(i>=(int)names.size())
{
return false;
}
assert(i<=(int)data.size());
mxArray * mx_data = data[i];
assert(!mxIsSparse(mx_data));
assert(mxGetNumberOfDimensions(mx_data) == 2);
//cout<<name<<": "<<mxGetM(mx_data)<<" "<<mxGetN(mx_data)<<endl;
assert(mxGetNumberOfElements(mx_data) == 1);
copy(
mxGetPr(mx_data),
mxGetPr(mx_data)+mxGetNumberOfElements(mx_data),
&d);
return true;
}
template <typename DerivedM>
inline bool igl::matlab::MatlabWorkspace::find_index(
const std::string & name,
Eigen::PlainObjectBase<DerivedM>& M)
{
if(!find(name,M))
{
return false;
}
M.array() -= 1;
return true;
}
//template <typename Data>
//bool igl::matlab::MatlabWorkspace::save(const Data & M, const std::string & name)
//{
// using namespace std;
// // If I don't know the type then I can't save it
// cerr<<"^MatlabWorkspace::save Error: Unknown data type. "<<
// name<<" not saved."<<endl;
// return false;
//}
#endif

View File

@@ -0,0 +1,56 @@
// 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
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_MATLAB_MEX_STREAM_H
#define IGL_MATLAB_MEX_STREAM_H
#include <iostream>
namespace igl
{
namespace matlab
{
// http://stackoverflow.com/a/249008/148668
// Class to implement "cout" for mex files to print to the matlab terminal
// window.
//
// Insert at the beginning of mexFunction():
// MexStream mout;
// std::streambuf *outbuf = std::cout.rdbuf(&mout);
// ...
// ALWAYS restore original buffer to avoid memory leak problems in matlab
// std::cout.rdbuf(outbuf);
//
class MexStream : public std::streambuf
{
public:
protected:
inline virtual std::streamsize xsputn(const char *s, std::streamsize n);
inline virtual int overflow(int c = EOF);
};
}
}
// Implementation
#include <mex.h>
inline std::streamsize igl::matlab::MexStream::xsputn(
const char *s,
std::streamsize n)
{
mexPrintf("%.*s",n,s);
mexEvalString("drawnow;"); // to dump string.
return n;
}
inline int igl::matlab::MexStream::overflow(int c)
{
if (c != EOF) {
mexPrintf("%.1s",&c);
mexEvalString("drawnow;"); // to dump string.
}
return 1;
}
#endif

View File

@@ -0,0 +1,330 @@
// 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
// obtain one at http://mozilla.org/MPL/2.0/.
#include <igl/matlab/matlabinterface.h>
// Implementation
// Init the MATLAB engine
// (no need to call it directly since it is automatically invoked by any other command)
IGL_INLINE void igl::matlab::mlinit(Engine** mlengine)
{
*mlengine = engOpen("\0");
}
// Closes the MATLAB engine
IGL_INLINE void igl::matlab::mlclose(Engine** mlengine)
{
engClose(*mlengine);
*mlengine = 0;
}
// Send a matrix to MATLAB
IGL_INLINE void igl::matlab::mlsetmatrix(Engine** mlengine, std::string name, const Eigen::MatrixXd& M)
{
if (*mlengine == 0)
mlinit(mlengine);
mxArray *A = mxCreateDoubleMatrix(M.rows(), M.cols(), mxREAL);
double *pM = mxGetPr(A);
int c = 0;
for(int j=0; j<M.cols();++j)
for(int i=0; i<M.rows();++i)
pM[c++] = double(M(i,j));
engPutVariable(*mlengine, name.c_str(), A);
mxDestroyArray(A);
}
// Send a matrix to MATLAB
IGL_INLINE void igl::matlab::mlsetmatrix(Engine** mlengine, std::string name, const Eigen::MatrixXf& M)
{
if (*mlengine == 0)
mlinit(mlengine);
mxArray *A = mxCreateDoubleMatrix(M.rows(), M.cols(), mxREAL);
double *pM = mxGetPr(A);
int c = 0;
for(int j=0; j<M.cols();++j)
for(int i=0; i<M.rows();++i)
pM[c++] = double(M(i,j));
engPutVariable(*mlengine, name.c_str(), A);
mxDestroyArray(A);
}
// Send a matrix to MATLAB
IGL_INLINE void igl::matlab::mlsetmatrix(Engine** mlengine, std::string name, const Eigen::MatrixXi& M)
{
if (*mlengine == 0)
mlinit(mlengine);
mxArray *A = mxCreateDoubleMatrix(M.rows(), M.cols(), mxREAL);
double *pM = mxGetPr(A);
int c = 0;
for(int j=0; j<M.cols();++j)
for(int i=0; i<M.rows();++i)
pM[c++] = double(M(i,j))+1;
engPutVariable(*mlengine, name.c_str(), A);
mxDestroyArray(A);
}
// Send a matrix to MATLAB
IGL_INLINE void igl::matlab::mlsetmatrix(Engine** mlengine, std::string name, const Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic >& M)
{
if (*mlengine == 0)
mlinit(mlengine);
mxArray *A = mxCreateDoubleMatrix(M.rows(), M.cols(), mxREAL);
double *pM = mxGetPr(A);
int c = 0;
for(int j=0; j<M.cols();++j)
for(int i=0; i<M.rows();++i)
pM[c++] = double(M(i,j))+1;
engPutVariable(*mlengine, name.c_str(), A);
mxDestroyArray(A);
}
// Receive a matrix from MATLAB
IGL_INLINE void igl::matlab::mlgetmatrix(Engine** mlengine, std::string name, Eigen::MatrixXd& M)
{
if (*mlengine == 0)
mlinit(mlengine);
unsigned long m = 0;
unsigned long n = 0;
std::vector<double> t;
mxArray *ary = engGetVariable(*mlengine, name.c_str());
if (ary == NULL)
{
m = 0;
n = 0;
M = Eigen::MatrixXd(0,0);
}
else
{
m = mxGetM(ary);
n = mxGetN(ary);
M = Eigen::MatrixXd(m,n);
double *pM = mxGetPr(ary);
int c = 0;
for(int j=0; j<M.cols();++j)
for(int i=0; i<M.rows();++i)
M(i,j) = pM[c++];
}
mxDestroyArray(ary);
}
IGL_INLINE void igl::matlab::mlgetmatrix(Engine** mlengine, std::string name, Eigen::MatrixXf& M)
{
if (*mlengine == 0)
mlinit(mlengine);
unsigned long m = 0;
unsigned long n = 0;
std::vector<double> t;
mxArray *ary = engGetVariable(*mlengine, name.c_str());
if (ary == NULL)
{
m = 0;
n = 0;
M = Eigen::MatrixXf(0,0);
}
else
{
m = mxGetM(ary);
n = mxGetN(ary);
M = Eigen::MatrixXf(m,n);
double *pM = mxGetPr(ary);
int c = 0;
for(int j=0; j<M.cols();++j)
for(int i=0; i<M.rows();++i)
M(i,j) = pM[c++];
}
mxDestroyArray(ary);
}
// Receive a matrix from MATLAB
IGL_INLINE void igl::matlab::mlgetmatrix(Engine** mlengine, std::string name, Eigen::MatrixXi& M)
{
if (*mlengine == 0)
mlinit(mlengine);
unsigned long m = 0;
unsigned long n = 0;
std::vector<double> t;
mxArray *ary = engGetVariable(*mlengine, name.c_str());
if (ary == NULL)
{
m = 0;
n = 0;
M = Eigen::MatrixXi(0,0);
}
else
{
m = mxGetM(ary);
n = mxGetN(ary);
M = Eigen::MatrixXi(m,n);
double *pM = mxGetPr(ary);
int c = 0;
for(int j=0; j<M.cols();++j)
for(int i=0; i<M.rows();++i)
M(i,j) = int(pM[c++])-1;
}
mxDestroyArray(ary);
}
// Receive a matrix from MATLAB
IGL_INLINE void igl::matlab::mlgetmatrix(Engine** mlengine, std::string name, Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic >& M)
{
if (*mlengine == 0)
mlinit(mlengine);
unsigned long m = 0;
unsigned long n = 0;
std::vector<double> t;
mxArray *ary = engGetVariable(*mlengine, name.c_str());
if (ary == NULL)
{
m = 0;
n = 0;
M = Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic >(0,0);
}
else
{
m = mxGetM(ary);
n = mxGetN(ary);
M = Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic >(m,n);
double *pM = mxGetPr(ary);
int c = 0;
for(int j=0; j<M.cols();++j)
for(int i=0; i<M.rows();++i)
M(i,j) = (unsigned int)(pM[c++])-1;
}
mxDestroyArray(ary);
}
// Send a single scalar to MATLAB
IGL_INLINE void igl::matlab::mlsetscalar(Engine** mlengine, std::string name, double s)
{
if (*mlengine == 0)
mlinit(mlengine);
Eigen::MatrixXd M(1,1);
M(0,0) = s;
mlsetmatrix(mlengine, name, M);
}
// Receive a single scalar from MATLAB
IGL_INLINE double igl::matlab::mlgetscalar(Engine** mlengine, std::string name)
{
if (*mlengine == 0)
mlinit(mlengine);
Eigen::MatrixXd M;
mlgetmatrix(mlengine, name,M);
return M(0,0);
}
// Execute arbitrary MATLAB code and return the MATLAB output
IGL_INLINE std::string igl::matlab::mleval(Engine** mlengine, std::string code)
{
if (*mlengine == 0)
mlinit(mlengine);
const char *matlab_code = code.c_str();
const int BUF_SIZE = 4096*4096;
// allocate on the heap to avoid running out of stack
std::string bufauto(BUF_SIZE+1, '\0');
char *buf = &bufauto[0];
assert(matlab_code != NULL);
// Use RAII ensure that on leaving this scope, the output buffer is
// always nullified (to prevent Matlab from accessing memory that might
// have already been deallocated).
struct cleanup {
Engine *m_ep;
cleanup(Engine *ep) : m_ep(ep) { }
~cleanup() { engOutputBuffer(m_ep, NULL, 0); }
} cleanup_obj(*mlengine);
if (buf != NULL)
engOutputBuffer(*mlengine, buf, BUF_SIZE);
int res = engEvalString(*mlengine, matlab_code);
if (res != 0) {
std::ostringstream oss;
oss << "ERROR: Matlab command failed with error code " << res << ".\n";
return oss.str();
}
if (buf[0] == '>' && buf[1] == '>' && buf[2] == ' ')
buf += 3;
if (buf[0] == '\n') ++buf;
return std::string(buf);
}
// Send a sparse matrix
IGL_INLINE void igl::matlab::mlsetmatrix(Engine** mlengine, std::string name, const Eigen::SparseMatrix<double>& M)
{
int count = 0;
// // Count non-zero
// for (unsigned k=0; k<M.outerSize(); ++k)
// for (Eigen::SparseMatrix<double>::InnerIterator it(M,k); it; ++it)
// if (it.value() != 0)
// ++count;
Eigen::MatrixXd T(M.nonZeros(),3);
for (unsigned k=0; k<(unsigned)M.outerSize(); ++k)
{
for (Eigen::SparseMatrix<double>::InnerIterator it(M,k); it; ++it)
{
T(count,0) = it.row();
T(count,1) = it.col();
T(count,2) = it.value();
++count;
}
}
T.col(0) = T.col(0).array()+1;
T.col(1) = T.col(1).array()+1;
mlsetmatrix(mlengine,"temp93765",T);
std::string temp = name + " = sparse(temp93765(:,1),temp93765(:,2),temp93765(:,3),"
+ std::to_string(M.rows()) + ","
+ std::to_string(M.cols()) + ");";
mleval(mlengine,temp);
mleval(mlengine,"clear temp93765");
}

View File

@@ -0,0 +1,90 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Daniele Panozzo <daniele.panozzo@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
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_MATLAB_MATLAB_INTERFACE_H
#define IGL_MATLAB_MATLAB_INTERFACE_H
#include "../igl_inline.h"
// WARNING: These functions require matlab installed
// Additional header folder required:
// /Applications/MATLAB_R2011a.app/extern/include
// Additional binary lib to be linked with:
// /Applications/MATLAB_R2011a.app/bin/maci64/libeng.dylib
// /Applications/MATLAB_R2011a.app/bin/maci64/libmx.dylib
// MAC ONLY:
// Add to the environment variables:
// DYLD_LIBRARY_PATH = /Applications/MATLAB_R2011a.app/bin/maci64/
// PATH = /opt/local/bin:/opt/local/sbin:/Applications/MATLAB_R2011a.app/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
#include <Eigen/Core>
#include <Eigen/Sparse>
#include <string>
#include <complex>
#include <cassert>
#include <map>
#include <string>
#include <vector>
#include <engine.h> // Matlab engine header
namespace igl
{
namespace matlab
{
// Init the MATLAB engine
// (no need to call it directly since it is automatically invoked by any other command)
IGL_INLINE void mlinit(Engine** engine);
// Closes the MATLAB engine
IGL_INLINE void mlclose(Engine** engine);
// Send a matrix to MATLAB
IGL_INLINE void mlsetmatrix(Engine** engine, std::string name, const Eigen::MatrixXd& M);
// Send a matrix to MATLAB
IGL_INLINE void mlsetmatrix(Engine** engine, std::string name, const Eigen::MatrixXf& M);
// Send a matrix to MATLAB
IGL_INLINE void mlsetmatrix(Engine** engine, std::string name, const Eigen::MatrixXi& M);
// Send a matrix to MATLAB
IGL_INLINE void mlsetmatrix(Engine** mlengine, std::string name, const Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic >& M);
// Receive a matrix from MATLAB
IGL_INLINE void mlgetmatrix(Engine** engine, std::string name, Eigen::MatrixXd& M);
// Receive a matrix from MATLAB
IGL_INLINE void mlgetmatrix(Engine** engine, std::string name, Eigen::MatrixXf& M);
// Receive a matrix from MATLAB
IGL_INLINE void mlgetmatrix(Engine** engine, std::string name, Eigen::MatrixXi& M);
// Receive a matrix from MATLAB
IGL_INLINE void mlgetmatrix(Engine** mlengine, std::string name, Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic >& M);
// Send a single scalar to MATLAB
IGL_INLINE void mlsetscalar(Engine** engine, std::string name, double s);
// Receive a single scalar from MATLAB
IGL_INLINE double mlgetscalar(Engine** engine, std::string name);
// Execute arbitrary MATLAB code and return the MATLAB output
IGL_INLINE std::string mleval(Engine** engine, std::string code);
// Send a sparse matrix to MATLAB
IGL_INLINE void mlsetmatrix(Engine** mlengine, std::string name, const Eigen::SparseMatrix<double>& M);
}
}
// Be sure that this is not compiled into libigl.a
#ifndef IGL_STATIC_LIBRARY
# include "matlabinterface.cpp"
#endif
#endif

View File

@@ -0,0 +1,17 @@
// 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
// obtain one at http://mozilla.org/MPL/2.0/.
#include "mexErrMsgTxt.h"
IGL_INLINE void igl::matlab::mexErrMsgTxt(bool assertion, const char * text)
{
if(!assertion)
{
::mexErrMsgTxt(text);
}
}

View File

@@ -0,0 +1,25 @@
// 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
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_MATLAB_MEXERRMSGTXT_H
#define IGL_MATLAB_MEXERRMSGTXT_H
#include "../igl_inline.h"
// Overload mexErrMsgTxt to check an assertion then print text only if
// assertion fails
#include "mex.h"
namespace igl
{
namespace matlab
{
// Wrapper for mexErrMsgTxt that only calls error if test fails
IGL_INLINE void mexErrMsgTxt(bool test, const char * message);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "mexErrMsgTxt.cpp"
#endif
#endif

View File

@@ -0,0 +1,83 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 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
// obtain one at http://mozilla.org/MPL/2.0/.
#include "parse_rhs.h"
#include <algorithm>
template <typename DerivedV>
IGL_INLINE void igl::matlab::parse_rhs_double(
const mxArray *prhs[],
Eigen::PlainObjectBase<DerivedV> & V)
{
using namespace Eigen;
// Use Eigen's map and cast to copy
V = Map< Matrix<double,Dynamic,Dynamic> >
(mxGetPr(prhs[0]),mxGetM(prhs[0]),mxGetN(prhs[0]))
.cast<typename DerivedV::Scalar>();
}
template <typename DerivedV>
IGL_INLINE void igl::matlab::parse_rhs_index(
const mxArray *prhs[],
Eigen::PlainObjectBase<DerivedV> & V)
{
parse_rhs_double(prhs,V);
V.array() -= 1;
}
template <typename MT>
IGL_INLINE void igl::matlab::parse_rhs(
const mxArray *prhs[],
Eigen::SparseMatrix<MT> & M)
{
using namespace Eigen;
using namespace std;
const mxArray * mx_data = prhs[0];
// Handle boring case where matrix is actually an empty dense matrix
if(mxGetNumberOfElements(mx_data) == 0)
{
M.resize(0,0);
return;
}
assert(mxIsSparse(mx_data));
assert(mxGetNumberOfDimensions(mx_data) == 2);
//cout<<name<<": "<<mxGetM(mx_data)<<" "<<mxGetN(mx_data)<<endl;
const int m = mxGetM(mx_data);
const int n = mxGetN(mx_data);
// TODO: It should be possible to directly load the data into the sparse
// matrix without going through the triplets
// Copy data immediately
double * pr = mxGetPr(mx_data);
mwIndex * ir = mxGetIr(mx_data);
mwIndex * jc = mxGetJc(mx_data);
vector<Triplet<MT> > MIJV;
MIJV.reserve(mxGetNumberOfElements(mx_data));
// Iterate over outside
int k = 0;
for(int j=0; j<n;j++)
{
// Iterate over inside
while(k<(int)jc[j+1])
{
//cout<<ir[k]<<" "<<j<<" "<<pr[k]<<endl;
assert((int)ir[k]<m);
assert((int)j<n);
MIJV.push_back(Triplet<MT >(ir[k],j,pr[k]));
k++;
}
}
M.resize(m,n);
M.setFromTriplets(MIJV.begin(),MIJV.end());
}
#ifdef IGL_STATIC_LIBRARY
template void igl::matlab::parse_rhs_index<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(mxArray_tag const**, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::matlab::parse_rhs_index<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(mxArray_tag const**, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
template void igl::matlab::parse_rhs_double<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(mxArray_tag const**, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
template void igl::matlab::parse_rhs_index<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(mxArray_tag const**, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
template void igl::matlab::parse_rhs_double<Eigen::Matrix<double, -1, 3, 1, -1, 3> >(mxArray_tag const**, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&);
#endif

View File

@@ -0,0 +1,42 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 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
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_MATLAB_PARSE_RHS_H
#define IGL_MATLAB_PARSE_RHS_H
#include <igl/igl_inline.h>
#include <mex.h>
#include <Eigen/Dense>
#include <Eigen/Sparse>
namespace igl
{
namespace matlab
{
// Reads in a matrix as a double
//
// Inputs:
// prhs points to rhs argument
// Outputs:
// V M by N matrix
template <typename DerivedV>
IGL_INLINE void parse_rhs_double(
const mxArray *prhs[],
Eigen::PlainObjectBase<DerivedV> & V);
// Reads in a matrix and subtracts 1
template <typename DerivedV>
IGL_INLINE void parse_rhs_index(
const mxArray *prhs[],
Eigen::PlainObjectBase<DerivedV> & V);
template <typename VType>
IGL_INLINE void parse_rhs(
const mxArray *prhs[],
Eigen::SparseMatrix<VType> & M);
}
};
#ifndef IGL_STATIC_LIBRARY
# include "parse_rhs.cpp"
#endif
#endif

View File

@@ -0,0 +1,99 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 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
// obtain one at http://mozilla.org/MPL/2.0/.
#include "prepare_lhs.h"
#include <algorithm>
template <typename DerivedV>
IGL_INLINE void igl::matlab::prepare_lhs_double(
const Eigen::PlainObjectBase<DerivedV> & V,
mxArray *plhs[])
{
using namespace std;
using namespace Eigen;
const int m = V.rows();
const int n = V.cols();
plhs[0] = mxCreateDoubleMatrix(m,n, mxREAL);
Eigen::Map< Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> >
map(mxGetPr(plhs[0]),m,n);
map = V.template cast<double>();
}
template <typename DerivedV>
IGL_INLINE void igl::matlab::prepare_lhs_logical(
const Eigen::PlainObjectBase<DerivedV> & V,
mxArray *plhs[])
{
using namespace std;
using namespace Eigen;
const int m = V.rows();
const int n = V.cols();
plhs[0] = mxCreateLogicalMatrix(m,n);
mxLogical * Vp = static_cast<mxLogical*>(mxGetData(plhs[0]));
Eigen::Map< Eigen::Matrix<mxLogical,Eigen::Dynamic,Eigen::Dynamic> >
map(static_cast<mxLogical*>(mxGetData(plhs[0])),m,n);
map = V.template cast<mxLogical>();
}
template <typename DerivedV>
IGL_INLINE void igl::matlab::prepare_lhs_index(
const Eigen::PlainObjectBase<DerivedV> & V,
mxArray *plhs[])
{
// Treat indices as reals
const auto Vd = (V.template cast<double>().array()+1).eval();
return prepare_lhs_double(Vd,plhs);
}
template <typename Vtype>
IGL_INLINE void igl::matlab::prepare_lhs_double(
const Eigen::SparseMatrix<Vtype> & M,
mxArray *plhs[])
{
using namespace std;
const int m = M.rows();
const int n = M.cols();
// THIS WILL NOT WORK FOR ROW-MAJOR
assert(n==M.outerSize());
const int nzmax = M.nonZeros();
plhs[0] = mxCreateSparse(m, n, nzmax, mxREAL);
mxArray * mx_data = plhs[0];
// Copy data immediately
double * pr = mxGetPr(mx_data);
mwIndex * ir = mxGetIr(mx_data);
mwIndex * jc = mxGetJc(mx_data);
// Iterate over outside
int k = 0;
for(int j=0; j<M.outerSize();j++)
{
jc[j] = k;
// Iterate over inside
for(typename Eigen::SparseMatrix<Vtype>::InnerIterator it (M,j); it; ++it)
{
// copy (cast to double)
pr[k] = it.value();
ir[k] = it.row();
k++;
}
}
jc[M.outerSize()] = k;
}
#ifdef IGL_STATIC_LIBRARY
template void igl::matlab::prepare_lhs_index<Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, mxArray_tag**);
template void igl::matlab::prepare_lhs_index<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, mxArray_tag**);
template void igl::matlab::prepare_lhs_double<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, mxArray_tag**);
template void igl::matlab::prepare_lhs_index<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, mxArray_tag**);
template void igl::matlab::prepare_lhs_logical<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, mxArray_tag**);
template void igl::matlab::prepare_lhs_double<Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, mxArray_tag**);
template void igl::matlab::prepare_lhs_logical<Eigen::Matrix<bool, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<bool, -1, 1, 0, -1, 1> > const&, mxArray_tag**);
template void igl::matlab::prepare_lhs_index<Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, mxArray_tag**);
template void igl::matlab::prepare_lhs_double<Eigen::Matrix<double, -1, 3, 1, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, mxArray_tag**);
template void igl::matlab::prepare_lhs_double<Eigen::Matrix<int, 1, -1, 1, 1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, 1, -1, 1, 1, -1> > const&, mxArray_tag**);
template void igl::matlab::prepare_lhs_double<Eigen::Matrix<int, 1, 3, 1, 1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> > const&, mxArray_tag**);
#endif

View File

@@ -0,0 +1,49 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 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
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_MATLAB_PREPARE_LHS_H
#define IGL_MATLAB_PREPARE_LHS_H
#include <igl/igl_inline.h>
#include <mex.h>
#include <Eigen/Dense>
#include <Eigen/Sparse>
namespace igl
{
namespace matlab
{
// Writes out a matrix as a double
//
// Inputs:
// prhs points to rhs argument
// Outputs:
// V M by N matrix
template <typename DerivedV>
IGL_INLINE void prepare_lhs_double(
const Eigen::PlainObjectBase<DerivedV> & V,
mxArray *plhs[]);
// Casts to logical
template <typename DerivedV>
IGL_INLINE void prepare_lhs_logical(
const Eigen::PlainObjectBase<DerivedV> & V,
mxArray *plhs[]);
// Writes out a matrix and adds 1
template <typename DerivedV>
IGL_INLINE void prepare_lhs_index(
const Eigen::PlainObjectBase<DerivedV> & V,
mxArray *plhs[]);
// SparseMatrix
template <typename Vtype>
IGL_INLINE void prepare_lhs_double(
const Eigen::SparseMatrix<Vtype> & V,
mxArray *plhs[]);
};
}
#ifndef IGL_STATIC_LIBRARY
# include "prepare_lhs.cpp"
#endif
#endif

View File

@@ -0,0 +1,16 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 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
// obtain one at http://mozilla.org/MPL/2.0/.
#include "requires_arg.h"
#include "mexErrMsgTxt.h"
#include "../C_STR.h"
IGL_INLINE void igl::matlab::requires_arg(const int i, const int nrhs, const char *name)
{
mexErrMsgTxt((i+1)<nrhs,
C_STR("Parameter '"<<name<<"' requires argument"));
}

View File

@@ -0,0 +1,29 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 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
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_REQUIRES_ARG_H
#define IGL_REQUIRES_ARG_H
#include "../igl_inline.h"
#include <mex.h>
namespace igl
{
namespace matlab
{
// Simply throw an error if (i+1)<rhs
//
// Input:
// i index of current arg
// nrhs total number of args
// name of current arg
IGL_INLINE void requires_arg(const int i, const int nrhs, const char *name);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "requires_arg.cpp"
#endif
#endif

View File

@@ -0,0 +1,50 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 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
// obtain one at http://mozilla.org/MPL/2.0/.
#include "validate_arg.h"
#include "requires_arg.h"
#include "mexErrMsgTxt.h"
#include "../C_STR.h"
IGL_INLINE void igl::matlab::validate_arg_scalar(
const int i, const int nrhs, const mxArray * prhs[], const char * name)
{
requires_arg(i,nrhs,name);
mexErrMsgTxt(mxGetN(prhs[i+1])==1 && mxGetM(prhs[i+1])==1,
C_STR("Parameter '"<<name<<"' requires scalar argument"));
}
IGL_INLINE void igl::matlab::validate_arg_logical(
const int i, const int nrhs, const mxArray * prhs[], const char * name)
{
requires_arg(i,nrhs,name);
mexErrMsgTxt(mxIsLogical(prhs[i+1]),
C_STR("Parameter '"<<name<<"' requires Logical argument"));
}
IGL_INLINE void igl::matlab::validate_arg_char(
const int i, const int nrhs, const mxArray * prhs[], const char * name)
{
requires_arg(i,nrhs,name);
mexErrMsgTxt(mxIsChar(prhs[i+1]),
C_STR("Parameter '"<<name<<"' requires char argument"));
}
IGL_INLINE void igl::matlab::validate_arg_double(
const int i, const int nrhs, const mxArray * prhs[], const char * name)
{
requires_arg(i,nrhs,name);
mexErrMsgTxt(mxIsDouble(prhs[i+1]),
C_STR("Parameter '"<<name<<"' requires double argument"));
}
IGL_INLINE void igl::matlab::validate_arg_function_handle(
const int i, const int nrhs, const mxArray * prhs[], const char * name)
{
requires_arg(i,nrhs,name);
mexErrMsgTxt(mxIsClass(prhs[i+1],"function_handle"),
C_STR("Parameter '"<<name<<"' requires function handle argument"));
}

View File

@@ -0,0 +1,38 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 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
// obtain one at http://mozilla.org/MPL/2.0/.
#ifndef IGL_VALIDATE_ARG_H
#define IGL_VALIDATE_ARG_H
#include "../igl_inline.h"
#include <mex.h>
namespace igl
{
namespace matlab
{
// Throw an error if arg i+1 is not a scalar
//
// Inputs:
// i index of current argument
// nrhs total number of arguments
// prhs pointer to arguments array
// name name of current argument
IGL_INLINE void validate_arg_scalar(
const int i, const int nrhs, const mxArray * prhs[], const char * name);
IGL_INLINE void validate_arg_logical(
const int i, const int nrhs, const mxArray * prhs[], const char * name);
IGL_INLINE void validate_arg_char(
const int i, const int nrhs, const mxArray * prhs[], const char * name);
IGL_INLINE void validate_arg_double(
const int i, const int nrhs, const mxArray * prhs[], const char * name);
IGL_INLINE void validate_arg_function_handle(
const int i, const int nrhs, const mxArray * prhs[], const char * name);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "validate_arg.cpp"
#endif
#endif