mirror of
https://github.com/QIDITECH/QIDISlicer.git
synced 2026-02-06 02:41:52 +03:00
update bundled_deps
This commit is contained in:
579
bundled_deps/libigl/igl/matlab/MatlabWorkspace.h
Normal file
579
bundled_deps/libigl/igl/matlab/MatlabWorkspace.h
Normal 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
|
||||
|
||||
56
bundled_deps/libigl/igl/matlab/MexStream.h
Normal file
56
bundled_deps/libigl/igl/matlab/MexStream.h
Normal 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
|
||||
330
bundled_deps/libigl/igl/matlab/matlabinterface.cpp
Normal file
330
bundled_deps/libigl/igl/matlab/matlabinterface.cpp
Normal 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");
|
||||
}
|
||||
90
bundled_deps/libigl/igl/matlab/matlabinterface.h
Normal file
90
bundled_deps/libigl/igl/matlab/matlabinterface.h
Normal 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
|
||||
17
bundled_deps/libigl/igl/matlab/mexErrMsgTxt.cpp
Normal file
17
bundled_deps/libigl/igl/matlab/mexErrMsgTxt.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
25
bundled_deps/libigl/igl/matlab/mexErrMsgTxt.h
Normal file
25
bundled_deps/libigl/igl/matlab/mexErrMsgTxt.h
Normal 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
|
||||
83
bundled_deps/libigl/igl/matlab/parse_rhs.cpp
Normal file
83
bundled_deps/libigl/igl/matlab/parse_rhs.cpp
Normal 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
|
||||
42
bundled_deps/libigl/igl/matlab/parse_rhs.h
Normal file
42
bundled_deps/libigl/igl/matlab/parse_rhs.h
Normal 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
|
||||
99
bundled_deps/libigl/igl/matlab/prepare_lhs.cpp
Normal file
99
bundled_deps/libigl/igl/matlab/prepare_lhs.cpp
Normal 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
|
||||
49
bundled_deps/libigl/igl/matlab/prepare_lhs.h
Normal file
49
bundled_deps/libigl/igl/matlab/prepare_lhs.h
Normal 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
|
||||
|
||||
16
bundled_deps/libigl/igl/matlab/requires_arg.cpp
Normal file
16
bundled_deps/libigl/igl/matlab/requires_arg.cpp
Normal 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"));
|
||||
}
|
||||
29
bundled_deps/libigl/igl/matlab/requires_arg.h
Normal file
29
bundled_deps/libigl/igl/matlab/requires_arg.h
Normal 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
|
||||
|
||||
50
bundled_deps/libigl/igl/matlab/validate_arg.cpp
Normal file
50
bundled_deps/libigl/igl/matlab/validate_arg.cpp
Normal 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"));
|
||||
}
|
||||
38
bundled_deps/libigl/igl/matlab/validate_arg.h
Normal file
38
bundled_deps/libigl/igl/matlab/validate_arg.h
Normal 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
|
||||
Reference in New Issue
Block a user