marching_cubes.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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. typename DerivedFaces::Scalar samples[12];
  88. unsigned char cubetype(0);
  89. unsigned int i;
  90. // get point indices of corner vertices
  91. for (i=0; i<8; ++i)
  92. {
  93. // get cube coordinates
  94. unsigned int _idx = cube_it;
  95. unsigned int X(x_res-1), Y(y_res-1);
  96. unsigned int x = _idx % X; _idx /= X;
  97. unsigned int y = _idx % Y; _idx /= Y;
  98. unsigned int z = _idx;
  99. // transform to point coordinates
  100. _idx = x + y*x_res + z*x_res*y_res;
  101. // add offset
  102. corner[i] = _idx + offsets_[i];
  103. }
  104. // determine cube type
  105. for (i=0; i<8; ++i)
  106. if (values(corner[i]) > isovalue)
  107. cubetype |= (1<<i);
  108. // trivial reject ?
  109. if (cubetype == 0 || cubetype == 255)
  110. continue;
  111. // compute samples on cube's edges
  112. if (edgeTable[cubetype]&1)
  113. samples[0] = add_vertex(values, points, corner[0], corner[1], vertices, num_vertices, edge2vertex);
  114. if (edgeTable[cubetype]&2)
  115. samples[1] = add_vertex(values, points, corner[1], corner[2], vertices, num_vertices, edge2vertex);
  116. if (edgeTable[cubetype]&4)
  117. samples[2] = add_vertex(values, points, corner[3], corner[2], vertices, num_vertices, edge2vertex);
  118. if (edgeTable[cubetype]&8)
  119. samples[3] = add_vertex(values, points, corner[0], corner[3], vertices, num_vertices, edge2vertex);
  120. if (edgeTable[cubetype]&16)
  121. samples[4] = add_vertex(values, points, corner[4], corner[5], vertices, num_vertices, edge2vertex);
  122. if (edgeTable[cubetype]&32)
  123. samples[5] = add_vertex(values, points, corner[5], corner[6], vertices, num_vertices, edge2vertex);
  124. if (edgeTable[cubetype]&64)
  125. samples[6] = add_vertex(values, points, corner[7], corner[6], vertices, num_vertices, edge2vertex);
  126. if (edgeTable[cubetype]&128)
  127. samples[7] = add_vertex(values, points, corner[4], corner[7], vertices, num_vertices, edge2vertex);
  128. if (edgeTable[cubetype]&256)
  129. samples[8] = add_vertex(values, points, corner[0], corner[4], vertices, num_vertices, edge2vertex);
  130. if (edgeTable[cubetype]&512)
  131. samples[9] = add_vertex(values, points, corner[1], corner[5], vertices, num_vertices, edge2vertex);
  132. if (edgeTable[cubetype]&1024)
  133. samples[10] = add_vertex(values, points, corner[2], corner[6], vertices, num_vertices, edge2vertex);
  134. if (edgeTable[cubetype]&2048)
  135. samples[11] = add_vertex(values, points, corner[3], corner[7], vertices, num_vertices, edge2vertex);
  136. // connect samples by triangles
  137. for (i=0; triTable[cubetype][0][i] != -1; i+=3 )
  138. {
  139. num_faces++;
  140. if (num_faces > faces.rows())
  141. faces.conservativeResize(faces.rows()+10000, Eigen::NoChange);
  142. faces.row(num_faces-1) <<
  143. samples[triTable[cubetype][0][i ]],
  144. samples[triTable[cubetype][0][i+1]],
  145. samples[triTable[cubetype][0][i+2]];
  146. }
  147. }
  148. vertices.conservativeResize(num_vertices, Eigen::NoChange);
  149. faces.conservativeResize(num_faces, Eigen::NoChange);
  150. }
  151. // Sparse index grid version
  152. MarchingCubes(const Eigen::MatrixBase<DerivedValues> &values,
  153. const Eigen::MatrixBase<DerivedPoints> &points,
  154. const Eigen::MatrixBase<DerivedIndices> &cubes,
  155. const double isovalue,
  156. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  157. Eigen::PlainObjectBase<DerivedFaces> &faces)
  158. {
  159. assert(values.cols() == 1);
  160. assert(points.cols() == 3);
  161. assert(cubes.cols() == 8);
  162. if(cubes.rows() == 0)
  163. {
  164. return;
  165. }
  166. faces.resize(10000,3);
  167. int num_faces = 0;
  168. vertices.resize(10000,3);
  169. int num_vertices = 0;
  170. unsigned n_cubes = cubes.rows();
  171. for (unsigned cube_it =0 ; cube_it < n_cubes; ++cube_it)
  172. {
  173. typedef Eigen::Matrix<typename DerivedIndices::Scalar, 1, 8> CubeIndexVector;
  174. typedef typename DerivedFaces::Scalar SampleScalar;
  175. CubeIndexVector cube = cubes.row(cube_it);
  176. SampleScalar samples[12];
  177. unsigned char cubetype(0);
  178. // determine cube type
  179. for (int i=0; i<8; ++i)
  180. {
  181. if (values[cube[i]] > isovalue)
  182. {
  183. cubetype |= (1<<i);
  184. }
  185. }
  186. // trivial reject ?
  187. if (cubetype == 0 || cubetype == 255)
  188. {
  189. continue;
  190. }
  191. // compute samples on cube's edges
  192. if (edgeTable[cubetype]&1)
  193. samples[0] = add_vertex(values, points, cube[0], cube[1], vertices, num_vertices, edge2vertex);
  194. if (edgeTable[cubetype]&2)
  195. samples[1] = add_vertex(values, points, cube[1], cube[2], vertices, num_vertices, edge2vertex);
  196. if (edgeTable[cubetype]&4)
  197. samples[2] = add_vertex(values, points, cube[3], cube[2], vertices, num_vertices, edge2vertex);
  198. if (edgeTable[cubetype]&8)
  199. samples[3] = add_vertex(values, points, cube[0], cube[3], vertices, num_vertices, edge2vertex);
  200. if (edgeTable[cubetype]&16)
  201. samples[4] = add_vertex(values, points, cube[4], cube[5], vertices, num_vertices, edge2vertex);
  202. if (edgeTable[cubetype]&32)
  203. samples[5] = add_vertex(values, points, cube[5], cube[6], vertices, num_vertices, edge2vertex);
  204. if (edgeTable[cubetype]&64)
  205. samples[6] = add_vertex(values, points, cube[7], cube[6], vertices, num_vertices, edge2vertex);
  206. if (edgeTable[cubetype]&128)
  207. samples[7] = add_vertex(values, points, cube[4], cube[7], vertices, num_vertices, edge2vertex);
  208. if (edgeTable[cubetype]&256)
  209. samples[8] = add_vertex(values, points, cube[0], cube[4], vertices, num_vertices, edge2vertex);
  210. if (edgeTable[cubetype]&512)
  211. samples[9] = add_vertex(values, points, cube[1], cube[5], vertices, num_vertices, edge2vertex);
  212. if (edgeTable[cubetype]&1024)
  213. samples[10] = add_vertex(values, points, cube[2], cube[6], vertices, num_vertices, edge2vertex);
  214. if (edgeTable[cubetype]&2048)
  215. samples[11] = add_vertex(values, points, cube[3], cube[7], vertices, num_vertices, edge2vertex);
  216. // connect samples by triangles
  217. for (int i=0; triTable[cubetype][0][i] != -1; i+=3 )
  218. {
  219. num_faces++;
  220. if (num_faces > faces.rows())
  221. {
  222. faces.conservativeResize(faces.rows()+10000, Eigen::NoChange);
  223. }
  224. faces.row(num_faces-1) <<
  225. samples[triTable[cubetype][0][i ]],
  226. samples[triTable[cubetype][0][i+1]],
  227. samples[triTable[cubetype][0][i+2]];
  228. }
  229. }
  230. vertices.conservativeResize(num_vertices, Eigen::NoChange);
  231. faces.conservativeResize(num_faces, Eigen::NoChange);
  232. }
  233. static typename DerivedFaces::Scalar add_vertex(const Eigen::MatrixBase<DerivedValues> &values,
  234. const Eigen::MatrixBase<DerivedPoints> &points,
  235. unsigned int i0,
  236. unsigned int i1,
  237. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  238. int &num_vertices,
  239. MyMap &edge2vertex)
  240. {
  241. // find vertex if it has been computed already
  242. MyMapIterator it = edge2vertex.find(EdgeKey(i0, i1));
  243. if (it != edge2vertex.end())
  244. {
  245. return it->second;
  246. }
  247. // generate new vertex
  248. const Eigen::Matrix<typename DerivedPoints::Scalar, 1, 3> & p0 = points.row(i0);
  249. const Eigen::Matrix<typename DerivedPoints::Scalar, 1, 3> & p1 = points.row(i1);
  250. typename DerivedValues::Scalar s0 = fabs(values[i0]);
  251. typename DerivedValues::Scalar s1 = fabs(values[i1]);
  252. typename DerivedValues::Scalar t = s0 / (s0+s1);
  253. num_vertices++;
  254. if (num_vertices > vertices.rows())
  255. {
  256. vertices.conservativeResize(vertices.rows()+10000, Eigen::NoChange);
  257. }
  258. // Linear interpolation based on linearly interpolating values
  259. vertices.row(num_vertices-1) = ((1.0f-t)*p0 + t*p1).template cast<typename DerivedVertices::Scalar>();
  260. edge2vertex[EdgeKey(i0, i1)] = num_vertices-1;
  261. return num_vertices-1;
  262. }
  263. // maps an edge to the sample vertex generated on it
  264. MyMap edge2vertex;
  265. };
  266. template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedFaces>
  267. IGL_INLINE void igl::copyleft::marching_cubes(
  268. const Eigen::MatrixBase<DerivedValues> &values,
  269. const Eigen::MatrixBase<DerivedPoints> &points,
  270. const unsigned x_res,
  271. const unsigned y_res,
  272. const unsigned z_res,
  273. const double isovalue,
  274. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  275. Eigen::PlainObjectBase<DerivedFaces> &faces)
  276. {
  277. typedef Eigen::MatrixXi Shim; /* DerivedIndices shim type is unused in this instantiation*/
  278. MarchingCubes<DerivedValues, DerivedPoints, DerivedVertices, Shim, DerivedFaces>
  279. mc(values, points, x_res, y_res, z_res, isovalue, vertices, faces);
  280. }
  281. template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedFaces>
  282. IGL_INLINE void igl::copyleft::marching_cubes(
  283. const Eigen::MatrixBase<DerivedValues> &values,
  284. const Eigen::MatrixBase<DerivedPoints> &points,
  285. const unsigned x_res,
  286. const unsigned y_res,
  287. const unsigned z_res,
  288. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  289. Eigen::PlainObjectBase<DerivedFaces> &faces)
  290. {
  291. typedef Eigen::MatrixXi Shim; /* DerivedIndices shim type is unused in this instantiation*/
  292. MarchingCubes<DerivedValues, DerivedPoints, DerivedVertices, Shim, DerivedFaces>
  293. mc(values, points, x_res, y_res, z_res, 0.0 /*isovalue*/, vertices, faces);
  294. }
  295. template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedIndices, typename DerivedFaces>
  296. IGL_INLINE void igl::copyleft::marching_cubes(
  297. const Eigen::MatrixBase<DerivedValues>& values,
  298. const Eigen::MatrixBase<DerivedPoints>& points,
  299. const Eigen::MatrixBase<DerivedIndices>& indices,
  300. const double isovalue,
  301. Eigen::PlainObjectBase<DerivedVertices>& vertices,
  302. Eigen::PlainObjectBase<DerivedFaces> &faces)
  303. {
  304. MarchingCubes<DerivedValues, DerivedPoints, DerivedVertices, DerivedIndices, DerivedFaces> mc(values, points, indices, isovalue, vertices, faces);
  305. }
  306. template <typename DerivedValues, typename DerivedPoints, typename DerivedVertices, typename DerivedIndices, typename DerivedFaces>
  307. IGL_INLINE void igl::copyleft::marching_cubes(
  308. const Eigen::MatrixBase<DerivedValues> &values,
  309. const Eigen::MatrixBase<DerivedPoints> &points,
  310. const Eigen::MatrixBase<DerivedIndices> & indices,
  311. Eigen::PlainObjectBase<DerivedVertices> &vertices,
  312. Eigen::PlainObjectBase<DerivedFaces> &faces)
  313. {
  314. MarchingCubes<DerivedValues, DerivedPoints, DerivedVertices, DerivedIndices, DerivedFaces> mc(values, points, indices, 0.0 /*isovalue*/, vertices, faces);
  315. }
  316. #ifdef IGL_STATIC_LIBRARY
  317. // Explicit template instantiation
  318. // generated by autoexplicit.sh
  319. 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> >&);
  320. // generated by autoexplicit.sh
  321. 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> >&);
  322. // generated by autoexplicit.sh
  323. 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> >&);
  324. // generated by autoexplicit.sh
  325. 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> >&);
  326. 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> >&);
  327. 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> >&);
  328. 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> >&);
  329. 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> >&);
  330. 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> >&);
  331. 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> >&);
  332. 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> >&);
  333. 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> >&);
  334. 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> >&);
  335. #endif