matlabinterface.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. //
  2. // IGL Lib - Simple C++ mesh library
  3. //
  4. // Copyright 2011, Daniele Panozzo. All rights reserved.
  5. // WARNING: These functions require matlab installed
  6. // Additional header folder required:
  7. // /Applications/MATLAB_R2010b.app/extern/include
  8. // Additional binary lib to be linked with:
  9. // /Applications/MATLAB_R2010b.app/bin/maci64/libeng.dylib
  10. // /Applications/MATLAB_R2010b.app/bin/maci64/libmx.dylib
  11. // MAC ONLY:
  12. // Add to the environment variables:
  13. // DYLD_LIBRARY_PATH = /Applications/MATLAB_R2010b.app/bin/maci64
  14. // PATH = /opt/local/bin:/opt/local/sbin:/Applications/MATLAB_R2010b.app/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
  15. #ifndef MATLAB_INTERFACE_H
  16. #define MATLAB_INTERFACE_H
  17. #include <Eigen/Core>
  18. #include <string>
  19. #include <complex>
  20. #include <cassert>
  21. #include <map>
  22. #include <string>
  23. #include <vector>
  24. #include "engine.h" // Matlab engine header
  25. namespace igl
  26. {
  27. // Global pointer to the matlab engine
  28. Engine* mlengine = 0;
  29. // Init the MATLAB engine
  30. // (no need to call it directly since it is automatically invoked by any other command)
  31. void mlinit()
  32. {
  33. mlengine = engOpen("\0");
  34. }
  35. // Closes the MATLAB engine
  36. void mlclose(Engine* engine)
  37. {
  38. engClose(mlengine);
  39. mlengine = 0;
  40. }
  41. // Send a matrix to MATLAB
  42. void mlsetmatrix(std::string name, Eigen::MatrixXd& M)
  43. {
  44. if (mlengine == 0)
  45. mlinit();
  46. mxArray *A = mxCreateDoubleMatrix(M.rows(), M.cols(), mxREAL);
  47. double *pM = mxGetPr(A);
  48. int c = 0;
  49. for(int j=0; j<M.cols();++j)
  50. for(int i=0; i<M.rows();++i)
  51. pM[c++] = double(M(i,j));
  52. engPutVariable(mlengine, name.c_str(), A);
  53. mxDestroyArray(A);
  54. }
  55. // Send a matrix to MATLAB
  56. void mlsetmatrix(std::string name, Eigen::MatrixXi& M)
  57. {
  58. if (mlengine == 0)
  59. mlinit();
  60. mxArray *A = mxCreateDoubleMatrix(M.rows(), M.cols(), mxREAL);
  61. double *pM = mxGetPr(A);
  62. int c = 0;
  63. for(int j=0; j<M.cols();++j)
  64. for(int i=0; i<M.rows();++i)
  65. pM[c++] = double(M(i,j))+1;
  66. engPutVariable(mlengine, name.c_str(), A);
  67. mxDestroyArray(A);
  68. }
  69. // Receive a matrix from MATLAB
  70. void mlgetmatrix(std::string name, Eigen::MatrixXd& M)
  71. {
  72. if (mlengine == 0)
  73. mlinit();
  74. unsigned long m = 0;
  75. unsigned long n = 0;
  76. std::vector<double> t;
  77. mxArray *ary = engGetVariable(mlengine, name.c_str());
  78. if (ary == NULL)
  79. {
  80. m = 0;
  81. n = 0;
  82. M = Eigen::MatrixXd(0,0);
  83. }
  84. else
  85. {
  86. m = mxGetM(ary);
  87. n = mxGetN(ary);
  88. M = Eigen::MatrixXd(m,n);
  89. double *pM = mxGetPr(ary);
  90. int c = 0;
  91. for(int j=0; j<M.cols();++j)
  92. for(int i=0; i<M.rows();++i)
  93. M(i,j) = pM[c++];
  94. }
  95. mxDestroyArray(ary);
  96. }
  97. // Receive a matrix from MATLAB
  98. void mlgetmatrix(std::string name, Eigen::MatrixXi& M)
  99. {
  100. if (mlengine == 0)
  101. mlinit();
  102. unsigned long m = 0;
  103. unsigned long n = 0;
  104. std::vector<double> t;
  105. mxArray *ary = engGetVariable(mlengine, name.c_str());
  106. if (ary == NULL)
  107. {
  108. m = 0;
  109. n = 0;
  110. M = Eigen::MatrixXi(0,0);
  111. }
  112. else
  113. {
  114. m = mxGetM(ary);
  115. n = mxGetN(ary);
  116. M = Eigen::MatrixXi(m,n);
  117. double *pM = mxGetPr(ary);
  118. int c = 0;
  119. for(int j=0; j<M.cols();++j)
  120. for(int i=0; i<M.rows();++i)
  121. M(i,j) = int(pM[c++])-1;
  122. }
  123. mxDestroyArray(ary);
  124. }
  125. // Send a single scalar to MATLAB
  126. void mlsetscalar(std::string name, double s)
  127. {
  128. if (mlengine == 0)
  129. mlinit();
  130. Eigen::MatrixXd M(1,1);
  131. M(0,0) = s;
  132. mlsetmatrix(name, M);
  133. }
  134. // Receive a single scalar from MATLAB
  135. double mlgetscalar(std::string name)
  136. {
  137. if (mlengine == 0)
  138. mlinit();
  139. Eigen::MatrixXd M;
  140. mlgetmatrix(name,M);
  141. return M(0,0);
  142. }
  143. // Execute arbitrary MATLAB code and return the MATLAB output
  144. std::string mleval(std::string code)
  145. {
  146. if (mlengine == 0)
  147. mlinit();
  148. const char *matlab_code = code.c_str();
  149. const int BUF_SIZE = 4096*4096;
  150. // allocate on the heap to avoid running out of stack
  151. std::string bufauto(BUF_SIZE+1, '\0');
  152. char *buf = &bufauto[0];
  153. assert(matlab_code != NULL);
  154. // Use RAII ensure that on leaving this scope, the output buffer is
  155. // always nullified (to prevent Matlab from accessing memory that might
  156. // have already been deallocated).
  157. struct cleanup {
  158. Engine *m_ep;
  159. cleanup(Engine *ep) : m_ep(ep) { }
  160. ~cleanup() { engOutputBuffer(m_ep, NULL, 0); }
  161. } cleanup_obj(mlengine);
  162. if (buf != NULL)
  163. engOutputBuffer(mlengine, buf, BUF_SIZE);
  164. int res = engEvalString(mlengine, matlab_code);
  165. if (res != 0) {
  166. std::ostringstream oss;
  167. oss << "ERROR: Matlab command failed with error code " << res << ".\n";
  168. return oss.str();
  169. }
  170. if (buf[0] == '>' && buf[1] == '>' && buf[2] == ' ')
  171. buf += 3;
  172. if (buf[0] == '\n') ++buf;
  173. return std::string(buf);
  174. }
  175. }
  176. #endif