unique.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "unique.h"
  9. #include "sort.h"
  10. #include "IndexComparison.h"
  11. #include "SortableRow.h"
  12. #include "sortrows.h"
  13. #include "list_to_matrix.h"
  14. #include "matrix_to_list.h"
  15. #include <algorithm>
  16. #include <iostream>
  17. #include <map>
  18. template <typename T>
  19. IGL_INLINE void igl::unique(
  20. const std::vector<T> & A,
  21. std::vector<T> & C,
  22. std::vector<size_t> & IA,
  23. std::vector<size_t> & IC)
  24. {
  25. using namespace std;
  26. std::vector<size_t> IM;
  27. std::vector<T> sortA;
  28. igl::sort(A,true,sortA,IM);
  29. // Original unsorted index map
  30. IA.resize(sortA.size());
  31. for(int i=0;i<(int)sortA.size();i++)
  32. {
  33. IA[i] = i;
  34. }
  35. IA.erase(
  36. std::unique(
  37. IA.begin(),
  38. IA.end(),
  39. igl::IndexEquals<const std::vector<T>& >(sortA)),IA.end());
  40. IC.resize(A.size());
  41. {
  42. int j = 0;
  43. for(int i = 0;i<(int)sortA.size();i++)
  44. {
  45. if(sortA[IA[j]] != sortA[i])
  46. {
  47. j++;
  48. }
  49. IC[IM[i]] = j;
  50. }
  51. }
  52. C.resize(IA.size());
  53. // Reindex IA according to IM
  54. for(int i = 0;i<(int)IA.size();i++)
  55. {
  56. IA[i] = IM[IA[i]];
  57. C[i] = A[IA[i]];
  58. }
  59. }
  60. template <typename T>
  61. IGL_INLINE void igl::unique(
  62. const std::vector<T> & A,
  63. std::vector<T> & C)
  64. {
  65. std::vector<size_t> IA,IC;
  66. return igl::unique(A,C,IA,IC);
  67. }
  68. template <
  69. typename DerivedA,
  70. typename DerivedC,
  71. typename DerivedIA,
  72. typename DerivedIC>
  73. IGL_INLINE void igl::unique(
  74. const Eigen::DenseBase<DerivedA> & A,
  75. Eigen::PlainObjectBase<DerivedC> & C,
  76. Eigen::PlainObjectBase<DerivedIA> & IA,
  77. Eigen::PlainObjectBase<DerivedIC> & IC)
  78. {
  79. using namespace std;
  80. using namespace Eigen;
  81. vector<typename DerivedA::Scalar > vA;
  82. vector<typename DerivedC::Scalar > vC;
  83. vector<size_t> vIA,vIC;
  84. matrix_to_list(A,vA);
  85. unique(vA,vC,vIA,vIC);
  86. list_to_matrix(vC,C);
  87. list_to_matrix(vIA,IA);
  88. list_to_matrix(vIC,IC);
  89. }
  90. template <
  91. typename DerivedA,
  92. typename DerivedC
  93. >
  94. IGL_INLINE void igl::unique(
  95. const Eigen::DenseBase<DerivedA> & A,
  96. Eigen::PlainObjectBase<DerivedC> & C)
  97. {
  98. using namespace std;
  99. using namespace Eigen;
  100. vector<typename DerivedA::Scalar > vA;
  101. vector<typename DerivedC::Scalar > vC;
  102. vector<size_t> vIA,vIC;
  103. matrix_to_list(A,vA);
  104. unique(vA,vC,vIA,vIC);
  105. list_to_matrix(vC,C);
  106. }
  107. // Obsolete slow version converting to vectors
  108. // template <typename DerivedA, typename DerivedIA, typename DerivedIC>
  109. // IGL_INLINE void igl::unique_rows(
  110. // const Eigen::PlainObjectBase<DerivedA>& A,
  111. // Eigen::PlainObjectBase<DerivedA>& C,
  112. // Eigen::PlainObjectBase<DerivedIA>& IA,
  113. // Eigen::PlainObjectBase<DerivedIC>& IC)
  114. // {
  115. // using namespace std;
  116. //
  117. // typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
  118. // vector<SortableRow<RowVector> > rows;
  119. // rows.resize(A.rows());
  120. // // Loop over rows
  121. // for(int i = 0;i<A.rows();i++)
  122. // {
  123. // RowVector ri = A.row(i);
  124. // rows[i] = SortableRow<RowVector>(ri);
  125. // }
  126. // vector<SortableRow<RowVector> > vC;
  127. //
  128. // // unique on rows
  129. // vector<size_t> vIA;
  130. // vector<size_t> vIC;
  131. // unique(rows,vC,vIA,vIC);
  132. //
  133. // // Convert to eigen
  134. // C.resize(vC.size(),A.cols());
  135. // IA.resize(vIA.size(),1);
  136. // IC.resize(vIC.size(),1);
  137. // for(int i = 0;i<C.rows();i++)
  138. // {
  139. // C.row(i) = vC[i].data;
  140. // IA(i) = vIA[i];
  141. // }
  142. // for(int i = 0;i<A.rows();i++)
  143. // {
  144. // IC(i) = vIC[i];
  145. // }
  146. // }
  147. // Obsolete
  148. // template <typename DerivedA, typename DerivedIA, typename DerivedIC>
  149. // IGL_INLINE void igl::unique_rows_many(
  150. // const Eigen::PlainObjectBase<DerivedA>& A,
  151. // Eigen::PlainObjectBase<DerivedA>& C,
  152. // Eigen::PlainObjectBase<DerivedIA>& IA,
  153. // Eigen::PlainObjectBase<DerivedIC>& IC)
  154. // {
  155. // using namespace std;
  156. // // frequency map
  157. // typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
  158. // IC.resize(A.rows(),1);
  159. // map<SortableRow<RowVector>, int> fm;
  160. // const int m = A.rows();
  161. // for(int i = 0;i<m;i++)
  162. // {
  163. // RowVector ri = A.row(i);
  164. // if(fm.count(SortableRow<RowVector>(ri)) == 0)
  165. // {
  166. // fm[SortableRow<RowVector>(ri)] = i;
  167. // }
  168. // IC(i) = fm[SortableRow<RowVector>(ri)];
  169. // }
  170. // IA.resize(fm.size(),1);
  171. // Eigen::VectorXi RIA(m);
  172. // C.resize(fm.size(),A.cols());
  173. // {
  174. // int i = 0;
  175. // for(typename map<SortableRow<RowVector > , int >::const_iterator fit = fm.begin();
  176. // fit != fm.end();
  177. // fit++)
  178. // {
  179. // IA(i) = fit->second;
  180. // RIA(fit->second) = i;
  181. // C.row(i) = fit->first.data;
  182. // i++;
  183. // }
  184. // }
  185. // // IC should index C
  186. // for(int i = 0;i<m;i++)
  187. // {
  188. // IC(i) = RIA(IC(i));
  189. // }
  190. // }
  191. template <typename DerivedA, typename DerivedIA, typename DerivedIC>
  192. IGL_INLINE void igl::unique_rows(
  193. const Eigen::DenseBase<DerivedA>& A,
  194. Eigen::PlainObjectBase<DerivedA>& C,
  195. Eigen::PlainObjectBase<DerivedIA>& IA,
  196. Eigen::PlainObjectBase<DerivedIC>& IC)
  197. {
  198. using namespace std;
  199. using namespace Eigen;
  200. VectorXi IM;
  201. DerivedA sortA;
  202. sortrows(A,true,sortA,IM);
  203. const int num_rows = sortA.rows();
  204. const int num_cols = sortA.cols();
  205. vector<int> vIA(num_rows);
  206. for(int i=0;i<num_rows;i++)
  207. {
  208. vIA[i] = i;
  209. }
  210. auto index_equal = [&sortA, &num_cols](const size_t i, const size_t j) {
  211. for (size_t c=0; c<num_cols; c++) {
  212. if (sortA(i,c) != sortA(j,c))
  213. return false;
  214. }
  215. return true;
  216. };
  217. vIA.erase(
  218. std::unique(
  219. vIA.begin(),
  220. vIA.end(),
  221. index_equal
  222. ),vIA.end());
  223. IC.resize(A.rows(),1);
  224. {
  225. int j = 0;
  226. for(int i = 0;i<num_rows;i++)
  227. {
  228. if(sortA.row(vIA[j]) != sortA.row(i))
  229. {
  230. j++;
  231. }
  232. IC(IM(i,0),0) = j;
  233. }
  234. }
  235. const int unique_rows = vIA.size();
  236. C.resize(unique_rows,A.cols());
  237. IA.resize(unique_rows,1);
  238. // Reindex IA according to IM
  239. for(int i = 0;i<unique_rows;i++)
  240. {
  241. IA(i,0) = IM(vIA[i],0);
  242. C.row(i) = A.row(IA(i,0));
  243. }
  244. }
  245. #ifdef IGL_STATIC_LIBRARY
  246. // Explicit template instantiation
  247. // generated by autoexplicit.sh
  248. template void igl::unique<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  249. // generated by autoexplicit.sh
  250. template void igl::unique<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  251. // generated by autoexplicit.sh
  252. template void igl::unique<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  253. template void igl::unique<int>(std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> >&, std::vector<size_t, std::allocator<size_t> >&, std::vector<size_t, std::allocator<size_t> >&);
  254. template void igl::unique_rows<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  255. template void igl::unique_rows<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::DenseBase<Eigen::Matrix<double, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  256. template void igl::unique_rows<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  257. template void igl::unique_rows<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::DenseBase<Eigen::Matrix<double, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  258. template void igl::unique_rows<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  259. template void igl::unique<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  260. template void igl::unique<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  261. template void igl::unique_rows<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
  262. template void igl::unique<int>(std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> >&);
  263. template void igl::unique<long>(std::vector<long, std::allocator<long> > const&, std::vector<long, std::allocator<long> >&, std::vector<size_t, std::allocator<size_t> >&, std::vector<size_t, std::allocator<size_t> >&);
  264. template void igl::unique_rows<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  265. template void igl::unique_rows<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  266. template void igl::unique<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  267. template void igl::unique<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::DenseBase<Eigen::Matrix<double, -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> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  268. template void igl::unique<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  269. template void igl::unique<double>(std::vector<double, std::allocator<double> > const&, std::vector<double, std::allocator<double> >&);
  270. template void igl::unique<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  271. template void igl::unique<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  272. template void igl::unique_rows<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  273. template void igl::unique<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
  274. #ifdef WIN32
  275. template void __cdecl igl::unique_rows<class Eigen::Matrix<int, -1, -1, 0, -1, -1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> >(class Eigen::DenseBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > const &, class Eigen::PlainObjectBase<class Eigen::Matrix<int, -1, -1, 0, -1, -1> > &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> > &, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> > &);
  276. #endif
  277. template void igl::unique_rows<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
  278. template void igl::unique_rows<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  279. #endif