marching_cubes.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. /*===========================================================================*\
  2. * *
  3. * IsoEx *
  4. * Copyright (C) 2002 by Computer Graphics Group, RWTH Aachen *
  5. * www.rwth-graphics.de *
  6. * *
  7. *---------------------------------------------------------------------------*
  8. * *
  9. * License *
  10. * *
  11. * This library is free software; you can redistribute it and/or modify it *
  12. * under the terms of the GNU Library General Public License as published *
  13. * by the Free Software Foundation, version 2. *
  14. * *
  15. * This library is distributed in the hope that it will be useful, but *
  16. * WITHOUT ANY WARRANTY; without even the implied warranty of *
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
  18. * Library General Public License for more details. *
  19. * *
  20. * You should have received a copy of the GNU Library General Public *
  21. * License along with this library; if not, write to the Free Software *
  22. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
  23. * *
  24. \*===========================================================================*/
  25. #include "marching_cubes.h"
  26. #include "marching_cubes_tables.h"
  27. #include <unordered_map>
  28. extern const int edgeTable[256];
  29. extern const int triTable[256][2][17];
  30. extern const int polyTable[8][16];
  31. template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedIndices, typename DerivedFaces>
  32. class MarchingCubes
  33. {
  34. struct EdgeKey
  35. {
  36. EdgeKey(unsigned i0, unsigned i1) : i0_(i0), i1_(i1) {}
  37. bool operator==(const EdgeKey& _rhs) const
  38. {
  39. return i0_ == _rhs.i0_ && i1_ == _rhs.i1_;
  40. }
  41. unsigned i0_, i1_;
  42. };
  43. struct EdgeHash
  44. {
  45. std::size_t operator()(const EdgeKey& key) const {
  46. std::size_t seed = 0;
  47. seed ^= key.i0_ + 0x9e3779b9 + (seed<<6) + (seed>>2); // Copied from boost::hash_combine
  48. seed ^= key.i1_ + 0x9e3779b9 + (seed<<6) + (seed>>2);
  49. return std::hash<std::size_t>()(seed);
  50. }
  51. };
  52. typedef std::unordered_map<EdgeKey, unsigned, EdgeHash> MyMap;
  53. typedef typename MyMap::const_iterator MyMapIterator;
  54. public:
  55. // Dense index grid version
  56. MarchingCubes(const Eigen::MatrixBase<DerivedValues> &values,
  57. const Eigen::MatrixBase<DerivedPoints> &points,
  58. const unsigned x_res,
  59. const unsigned y_res,
  60. const unsigned z_res,
  61. const double isovalue,
  62. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  63. Eigen::PlainObjectBase<DerivedFaces> &faces)
  64. {
  65. assert(values.cols() == 1);
  66. assert(points.cols() == 3);
  67. if(x_res <2 || y_res<2 ||z_res<2)
  68. return;
  69. faces.resize(10000,3);
  70. int num_faces = 0;
  71. vertices.resize(10000,3);
  72. int num_vertices = 0;
  73. unsigned n_cubes = (x_res-1) * (y_res-1) * (z_res-1);
  74. assert(unsigned(points.rows()) == x_res * y_res * z_res);
  75. unsigned int offsets_[8];
  76. offsets_[0] = 0;
  77. offsets_[1] = 1;
  78. offsets_[2] = 1 + x_res;
  79. offsets_[3] = x_res;
  80. offsets_[4] = x_res*y_res;
  81. offsets_[5] = 1 + x_res*y_res;
  82. offsets_[6] = 1 + x_res + x_res*y_res;
  83. offsets_[7] = x_res + x_res*y_res;
  84. for (unsigned cube_it =0 ; cube_it < n_cubes; ++cube_it)
  85. {
  86. unsigned corner[8];
  87. // get point indices of corner vertices
  88. for (int i=0; i<8; ++i)
  89. {
  90. // get cube coordinates
  91. unsigned int _idx = cube_it;
  92. unsigned int X(x_res-1), Y(y_res-1);
  93. unsigned int x = _idx % X; _idx /= X;
  94. unsigned int y = _idx % Y; _idx /= Y;
  95. unsigned int z = _idx;
  96. // transform to point coordinates
  97. _idx = x + y*x_res + z*x_res*y_res;
  98. // add offset
  99. corner[i] = _idx + offsets_[i];
  100. }
  101. add_cube(values,points,isovalue,corner,vertices,num_vertices,faces,num_faces,edge2vertex);
  102. }
  103. vertices.conservativeResize(num_vertices, Eigen::NoChange);
  104. faces.conservativeResize(num_faces, Eigen::NoChange);
  105. }
  106. // Sparse index grid version
  107. MarchingCubes(const Eigen::MatrixBase<DerivedValues> &values,
  108. const Eigen::MatrixBase<DerivedPoints> &points,
  109. const Eigen::MatrixBase<DerivedIndices> &cubes,
  110. const double isovalue,
  111. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  112. Eigen::PlainObjectBase<DerivedFaces> &faces)
  113. {
  114. assert(values.cols() == 1);
  115. assert(points.cols() == 3);
  116. assert(cubes.cols() == 8);
  117. if(cubes.rows() == 0)
  118. {
  119. return;
  120. }
  121. faces.resize(10000,3);
  122. int num_faces = 0;
  123. vertices.resize(10000,3);
  124. int num_vertices = 0;
  125. unsigned n_cubes = cubes.rows();
  126. for (unsigned cube_it =0 ; cube_it < n_cubes; ++cube_it)
  127. {
  128. typedef Eigen::Matrix<typename DerivedIndices::Scalar, 1, 8> CubeIndexVector;
  129. CubeIndexVector corner = cubes.row(cube_it);
  130. add_cube(values,points,isovalue,corner.data(),vertices,num_vertices,faces,num_faces,edge2vertex);
  131. }
  132. vertices.conservativeResize(num_vertices, Eigen::NoChange);
  133. faces.conservativeResize(num_faces, Eigen::NoChange);
  134. }
  135. // Dense index grid function version
  136. template <typename DerivedValue, typename DerivedPoint>
  137. MarchingCubes(
  138. const std::function< DerivedValue(const DerivedPoint & ) > & value_fun,
  139. const Eigen::MatrixBase<DerivedPoints> &points,
  140. const unsigned x_res,
  141. const unsigned y_res,
  142. const unsigned z_res,
  143. const double isovalue,
  144. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  145. Eigen::PlainObjectBase<DerivedFaces> &faces)
  146. {
  147. assert(points.cols() == 3);
  148. if(x_res <2 || y_res<2 ||z_res<2)
  149. return;
  150. faces.resize(10000,3);
  151. int num_faces = 0;
  152. vertices.resize(10000,3);
  153. int num_vertices = 0;
  154. unsigned n_cubes = (x_res-1) * (y_res-1) * (z_res-1);
  155. assert(unsigned(points.rows()) == x_res * y_res * z_res);
  156. unsigned int offsets_[8];
  157. offsets_[0] = 0;
  158. offsets_[1] = 1;
  159. offsets_[2] = 1 + x_res;
  160. offsets_[3] = x_res;
  161. offsets_[4] = x_res*y_res;
  162. offsets_[5] = 1 + x_res*y_res;
  163. offsets_[6] = 1 + x_res + x_res*y_res;
  164. offsets_[7] = x_res + x_res*y_res;
  165. for (unsigned cube_it =0 ; cube_it < n_cubes; ++cube_it)
  166. {
  167. unsigned corner[8];
  168. // get point indices of corner vertices
  169. for (int i=0; i<8; ++i)
  170. {
  171. // get cube coordinates
  172. unsigned int _idx = cube_it;
  173. unsigned int X(x_res-1), Y(y_res-1);
  174. unsigned int x = _idx % X; _idx /= X;
  175. unsigned int y = _idx % Y; _idx /= Y;
  176. unsigned int z = _idx;
  177. // transform to point coordinates
  178. _idx = x + y*x_res + z*x_res*y_res;
  179. // add offset
  180. corner[i] = _idx + offsets_[i];
  181. }
  182. add_cube(value_fun,points,isovalue,corner,vertices,num_vertices,faces,num_faces,edge2vertex);
  183. }
  184. vertices.conservativeResize(num_vertices, Eigen::NoChange);
  185. faces.conservativeResize(num_faces, Eigen::NoChange);
  186. }
  187. template <typename CubeIndexType>
  188. static void add_cube(
  189. const Eigen::MatrixBase<DerivedValues> &values,
  190. const Eigen::MatrixBase<DerivedPoints> &points,
  191. const double isovalue,
  192. const CubeIndexType corner[],
  193. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  194. int &num_vertices,
  195. Eigen::PlainObjectBase<DerivedFaces> &faces,
  196. int & num_faces,
  197. MyMap &edge2vertex)
  198. {
  199. typedef typename DerivedFaces::Scalar SampleScalar;
  200. SampleScalar samples[12];
  201. unsigned char cubetype(0);
  202. // determine cube type
  203. for (int i=0; i<8; ++i)
  204. {
  205. if (values(corner[i]) > isovalue)
  206. {
  207. cubetype |= (1<<i);
  208. }
  209. }
  210. // trivial reject ?
  211. if (cubetype == 0 || cubetype == 255)
  212. {
  213. return;
  214. }
  215. // compute samples on cube's edges
  216. if (edgeTable[cubetype]&1)
  217. samples[0] = add_vertex(values, points, isovalue, corner[0], corner[1], vertices, num_vertices, edge2vertex);
  218. if (edgeTable[cubetype]&2)
  219. samples[1] = add_vertex(values, points, isovalue, corner[1], corner[2], vertices, num_vertices, edge2vertex);
  220. if (edgeTable[cubetype]&4)
  221. samples[2] = add_vertex(values, points, isovalue, corner[3], corner[2], vertices, num_vertices, edge2vertex);
  222. if (edgeTable[cubetype]&8)
  223. samples[3] = add_vertex(values, points, isovalue, corner[0], corner[3], vertices, num_vertices, edge2vertex);
  224. if (edgeTable[cubetype]&16)
  225. samples[4] = add_vertex(values, points, isovalue, corner[4], corner[5], vertices, num_vertices, edge2vertex);
  226. if (edgeTable[cubetype]&32)
  227. samples[5] = add_vertex(values, points, isovalue, corner[5], corner[6], vertices, num_vertices, edge2vertex);
  228. if (edgeTable[cubetype]&64)
  229. samples[6] = add_vertex(values, points, isovalue, corner[7], corner[6], vertices, num_vertices, edge2vertex);
  230. if (edgeTable[cubetype]&128)
  231. samples[7] = add_vertex(values, points, isovalue, corner[4], corner[7], vertices, num_vertices, edge2vertex);
  232. if (edgeTable[cubetype]&256)
  233. samples[8] = add_vertex(values, points, isovalue, corner[0], corner[4], vertices, num_vertices, edge2vertex);
  234. if (edgeTable[cubetype]&512)
  235. samples[9] = add_vertex(values, points, isovalue, corner[1], corner[5], vertices, num_vertices, edge2vertex);
  236. if (edgeTable[cubetype]&1024)
  237. samples[10] = add_vertex(values, points, isovalue, corner[2], corner[6], vertices, num_vertices, edge2vertex);
  238. if (edgeTable[cubetype]&2048)
  239. samples[11] = add_vertex(values, points, isovalue, corner[3], corner[7], vertices, num_vertices, edge2vertex);
  240. // connect samples by triangles
  241. for (int i=0; triTable[cubetype][0][i] != -1; i+=3 )
  242. {
  243. num_faces++;
  244. if (num_faces > faces.rows())
  245. {
  246. faces.conservativeResize(faces.rows()+10000, Eigen::NoChange);
  247. }
  248. faces.row(num_faces-1) <<
  249. samples[triTable[cubetype][0][i ]],
  250. samples[triTable[cubetype][0][i+1]],
  251. samples[triTable[cubetype][0][i+2]];
  252. }
  253. };
  254. template <typename DerivedValue, typename DerivedPoint, typename CubeIndexType>
  255. static void add_cube(
  256. const std::function< DerivedValue(const DerivedPoint & ) > & value_fun,
  257. const Eigen::MatrixBase<DerivedPoints> &points,
  258. const double isovalue,
  259. const CubeIndexType corner[],
  260. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  261. int &num_vertices,
  262. Eigen::PlainObjectBase<DerivedFaces> &faces,
  263. int & num_faces,
  264. MyMap &edge2vertex)
  265. {
  266. typedef typename DerivedFaces::Scalar SampleScalar;
  267. SampleScalar samples[12];
  268. unsigned char cubetype(0);
  269. // determine cube type
  270. for (int i=0; i<8; ++i)
  271. {
  272. if (value_fun(points.row(corner[i])) > isovalue)
  273. {
  274. cubetype |= (1<<i);
  275. }
  276. }
  277. // trivial reject ?
  278. if (cubetype == 0 || cubetype == 255)
  279. {
  280. return;
  281. }
  282. // compute samples on cube's edges
  283. if (edgeTable[cubetype]&1)
  284. samples[0] = add_vertex(value_fun, points, isovalue, corner[0], corner[1], vertices, num_vertices, edge2vertex);
  285. if (edgeTable[cubetype]&2)
  286. samples[1] = add_vertex(value_fun, points, isovalue, corner[1], corner[2], vertices, num_vertices, edge2vertex);
  287. if (edgeTable[cubetype]&4)
  288. samples[2] = add_vertex(value_fun, points, isovalue, corner[3], corner[2], vertices, num_vertices, edge2vertex);
  289. if (edgeTable[cubetype]&8)
  290. samples[3] = add_vertex(value_fun, points, isovalue, corner[0], corner[3], vertices, num_vertices, edge2vertex);
  291. if (edgeTable[cubetype]&16)
  292. samples[4] = add_vertex(value_fun, points, isovalue, corner[4], corner[5], vertices, num_vertices, edge2vertex);
  293. if (edgeTable[cubetype]&32)
  294. samples[5] = add_vertex(value_fun, points, isovalue, corner[5], corner[6], vertices, num_vertices, edge2vertex);
  295. if (edgeTable[cubetype]&64)
  296. samples[6] = add_vertex(value_fun, points, isovalue, corner[7], corner[6], vertices, num_vertices, edge2vertex);
  297. if (edgeTable[cubetype]&128)
  298. samples[7] = add_vertex(value_fun, points, isovalue, corner[4], corner[7], vertices, num_vertices, edge2vertex);
  299. if (edgeTable[cubetype]&256)
  300. samples[8] = add_vertex(value_fun, points, isovalue, corner[0], corner[4], vertices, num_vertices, edge2vertex);
  301. if (edgeTable[cubetype]&512)
  302. samples[9] = add_vertex(value_fun, points, isovalue, corner[1], corner[5], vertices, num_vertices, edge2vertex);
  303. if (edgeTable[cubetype]&1024)
  304. samples[10] = add_vertex(value_fun, points, isovalue, corner[2], corner[6], vertices, num_vertices, edge2vertex);
  305. if (edgeTable[cubetype]&2048)
  306. samples[11] = add_vertex(value_fun, points, isovalue, corner[3], corner[7], vertices, num_vertices, edge2vertex);
  307. // connect samples by triangles
  308. for (int i=0; triTable[cubetype][0][i] != -1; i+=3 )
  309. {
  310. num_faces++;
  311. if (num_faces > faces.rows())
  312. {
  313. faces.conservativeResize(faces.rows()+10000, Eigen::NoChange);
  314. }
  315. faces.row(num_faces-1) <<
  316. samples[triTable[cubetype][0][i ]],
  317. samples[triTable[cubetype][0][i+1]],
  318. samples[triTable[cubetype][0][i+2]];
  319. }
  320. };
  321. static typename DerivedFaces::Scalar add_vertex(
  322. const Eigen::MatrixBase<DerivedValues> &values,
  323. const Eigen::MatrixBase<DerivedPoints> &points,
  324. const double isovalue,
  325. unsigned int i0,
  326. unsigned int i1,
  327. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  328. int &num_vertices,
  329. MyMap &edge2vertex)
  330. {
  331. // find vertex if it has been computed already
  332. MyMapIterator it = edge2vertex.find(EdgeKey(i0, i1));
  333. if (it != edge2vertex.end())
  334. {
  335. return it->second;
  336. }
  337. // generate new vertex
  338. const Eigen::Matrix<typename DerivedPoints::Scalar, 1, 3> & p0 = points.row(i0);
  339. const Eigen::Matrix<typename DerivedPoints::Scalar, 1, 3> & p1 = points.row(i1);
  340. typename DerivedValues::Scalar s0 = fabs(values(i0)-isovalue);
  341. typename DerivedValues::Scalar s1 = fabs(values(i1)-isovalue);
  342. typename DerivedValues::Scalar t = s0 / (s0+s1);
  343. num_vertices++;
  344. if (num_vertices > vertices.rows())
  345. {
  346. vertices.conservativeResize(vertices.rows()+10000, Eigen::NoChange);
  347. }
  348. //
  349. // Linear interpolation based on linearly interpolating values
  350. vertices.row(num_vertices-1) = ((1.0f-t)*p0 + t*p1).template cast<typename DerivedVertices::Scalar>();
  351. edge2vertex[EdgeKey(i0, i1)] = num_vertices-1;
  352. return num_vertices-1;
  353. }
  354. template <typename DerivedValue, typename DerivedPoint>
  355. static typename DerivedFaces::Scalar add_vertex(
  356. const std::function< DerivedValue(const DerivedPoint & ) > & value_fun,
  357. const Eigen::MatrixBase<DerivedPoints> &points,
  358. const double isovalue,
  359. unsigned int i0,
  360. unsigned int i1,
  361. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  362. int &num_vertices,
  363. MyMap &edge2vertex)
  364. {
  365. // find vertex if it has been computed already
  366. MyMapIterator it = edge2vertex.find(EdgeKey(i0, i1));
  367. if (it != edge2vertex.end())
  368. {
  369. return it->second;
  370. }
  371. num_vertices++;
  372. if (num_vertices > vertices.rows())
  373. {
  374. vertices.conservativeResize(vertices.rows()+10000, Eigen::NoChange);
  375. }
  376. // generate new vertex
  377. typedef Eigen::Matrix<typename DerivedPoints::Scalar, 1, 3> RowVector3S;
  378. const RowVector3S & p0 = points.row(i0);
  379. const RowVector3S & p1 = points.row(i1);
  380. // Linear interpolation based on linearly interpolating values
  381. //typename DerivedValues::Scalar s0 = fabs(value_fun(points.row(i0))-isovalue);
  382. //typename DerivedValues::Scalar s1 = fabs(value_fun(points.row(i1))-isovalue);
  383. //typename DerivedValues::Scalar t = s0 / (s0+s1);
  384. const DerivedValue v1 = value_fun(p1);
  385. double t0 = (v1>isovalue)?0:1;
  386. double t1 = (v1>isovalue)?1:0;
  387. double t;
  388. for(int j = 0;j<10;j++)
  389. {
  390. t = 0.5*(t0+t1);
  391. const double val = value_fun( ((1.0f-t)*p0 + t*p1) );
  392. if( val > isovalue )
  393. {
  394. t1 = t;
  395. }else
  396. {
  397. t0 = t;
  398. }
  399. }
  400. vertices.row(num_vertices-1) = ((1.0f-t)*p0 + t*p1).template cast<typename DerivedVertices::Scalar>();
  401. edge2vertex[EdgeKey(i0, i1)] = num_vertices-1;
  402. return num_vertices-1;
  403. }
  404. // maps an edge to the sample vertex generated on it
  405. MyMap edge2vertex;
  406. };
  407. template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedFaces>
  408. IGL_INLINE void igl::copyleft::marching_cubes(
  409. const Eigen::MatrixBase<DerivedValues> &values,
  410. const Eigen::MatrixBase<DerivedPoints> &points,
  411. const unsigned x_res,
  412. const unsigned y_res,
  413. const unsigned z_res,
  414. const double isovalue,
  415. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  416. Eigen::PlainObjectBase<DerivedFaces> &faces)
  417. {
  418. typedef Eigen::MatrixXi Shim; /* DerivedIndices shim type is unused in this instantiation*/
  419. MarchingCubes<DerivedValues, DerivedPoints, DerivedVertices, Shim, DerivedFaces>
  420. mc(values, points, x_res, y_res, z_res, isovalue, vertices, faces);
  421. }
  422. template <
  423. typename DerivedValue,
  424. typename DerivedPoint,
  425. typename DerivedPoints,
  426. typename DerivedVertices,
  427. typename DerivedFaces>
  428. IGL_INLINE void igl::copyleft::marching_cubes(
  429. const std::function< DerivedValue(const DerivedPoint & ) > & value_fun,
  430. const Eigen::MatrixBase<DerivedPoints> &points,
  431. const unsigned x_res,
  432. const unsigned y_res,
  433. const unsigned z_res,
  434. const double isovalue,
  435. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  436. Eigen::PlainObjectBase<DerivedFaces> &faces)
  437. {
  438. MarchingCubes<
  439. Eigen::Matrix<DerivedValue,Eigen::Dynamic,1>, /* unnecessary */
  440. DerivedPoints, DerivedVertices,
  441. Eigen::Matrix<int,Eigen::Dynamic,1>, /* unnecessary */
  442. DerivedFaces> mc(value_fun, points, x_res, y_res, z_res, isovalue, vertices, faces);
  443. }
  444. template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedFaces>
  445. IGL_INLINE void igl::copyleft::marching_cubes(
  446. const Eigen::MatrixBase<DerivedValues> &values,
  447. const Eigen::MatrixBase<DerivedPoints> &points,
  448. const unsigned x_res,
  449. const unsigned y_res,
  450. const unsigned z_res,
  451. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  452. Eigen::PlainObjectBase<DerivedFaces> &faces)
  453. {
  454. typedef Eigen::MatrixXi Shim; /* DerivedIndices shim type is unused in this instantiation*/
  455. MarchingCubes<DerivedValues, DerivedPoints, DerivedVertices, Shim, DerivedFaces>
  456. mc(values, points, x_res, y_res, z_res, 0.0 /*isovalue*/, vertices, faces);
  457. }
  458. template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedIndices, typename DerivedFaces>
  459. IGL_INLINE void igl::copyleft::marching_cubes(
  460. const Eigen::MatrixBase<DerivedValues>& values,
  461. const Eigen::MatrixBase<DerivedPoints>& points,
  462. const Eigen::MatrixBase<DerivedIndices>& indices,
  463. const double isovalue,
  464. Eigen::PlainObjectBase<DerivedVertices>& vertices,
  465. Eigen::PlainObjectBase<DerivedFaces> &faces)
  466. {
  467. MarchingCubes<DerivedValues, DerivedPoints, DerivedVertices, DerivedIndices, DerivedFaces> mc(values, points, indices, isovalue, vertices, faces);
  468. }
  469. template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedIndices, typename DerivedFaces>
  470. IGL_INLINE void igl::copyleft::marching_cubes(
  471. const Eigen::MatrixBase<DerivedValues> &values,
  472. const Eigen::MatrixBase<DerivedPoints> &points,
  473. const Eigen::MatrixBase<DerivedIndices> & indices,
  474. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  475. Eigen::PlainObjectBase<DerivedFaces> &faces)
  476. {
  477. MarchingCubes<DerivedValues, DerivedPoints, DerivedVertices, DerivedIndices, DerivedFaces> mc(values, points, indices, 0.0 /*isovalue*/, vertices, faces);
  478. }
  479. #ifdef IGL_STATIC_LIBRARY
  480. // Explicit template instantiation
  481. template void igl::copyleft::marching_cubes<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
  482. template void igl::copyleft::marching_cubes<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
  483. template void igl::copyleft::marching_cubes<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
  484. template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
  485. template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, unsigned int, unsigned int, unsigned int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  486. template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(const Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, const Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, const Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  487. template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(const Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, const Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, const Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  488. template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(const Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, const Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, const Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  489. template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(const Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, const Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, const Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  490. template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 8, 0, -1, 8>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(const Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, const Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, const Eigen::MatrixBase<Eigen::Matrix<int, -1, 8, 0, -1, 8> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  491. template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>,Eigen::Matrix<double, -1, -1, 0, -1, -1>,Eigen::Matrix<double, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, 3, 0, -1, 3> >(const Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&,const Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&,const Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
  492. template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>,Eigen::Matrix<double, -1, -1, 0, -1, -1>,Eigen::Matrix<double, -1, -1, 0, -1, -1>,Eigen::Matrix<int, -1, 8, 0, -1, 8>,Eigen::Matrix<int, -1, 3, 0, -1, 3> >(const Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&,const Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&,const Eigen::MatrixBase<Eigen::Matrix<int, -1, 8, 0, -1, 8> >&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&,Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
  493. template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>,Eigen::Matrix<double, -1, 3, 0, -1, 3>,Eigen::Matrix<double, -1, 3, 0, -1, 3>,Eigen::Matrix<int, -1, 8, 0, -1, 8>,Eigen::Matrix<int, -1, 3, 0, -1, 3> >(const Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&,const Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&,const Eigen::MatrixBase<Eigen::Matrix<int, -1, 8, 0, -1, 8> >&,Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&,Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
  494. template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  495. template void igl::copyleft::marching_cubes<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, unsigned int, unsigned int, unsigned int, double, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  496. #endif