remove_duplicates.cpp 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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 "remove_duplicates.h"
  9. #include <vector>
  10. //template <typename T, typename S>
  11. //IGL_INLINE void igl::remove_duplicates(
  12. // const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V,
  13. // const Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &F,
  14. // Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV,
  15. // Eigen::Matrix<S, Eigen::Dynamic, Eigen::Dynamic> &NF,
  16. // Eigen::Matrix<S, Eigen::Dynamic, 1> &I,
  17. // const double epsilon)
  18. template <typename DerivedV, typename DerivedF>
  19. IGL_INLINE void igl::remove_duplicates(
  20. const Eigen::PlainObjectBase<DerivedV> &V,
  21. const Eigen::PlainObjectBase<DerivedF> &F,
  22. Eigen::PlainObjectBase<DerivedV> &NV,
  23. Eigen::PlainObjectBase<DerivedF> &NF,
  24. Eigen::Matrix<typename DerivedF::Scalar, Eigen::Dynamic, 1> &I,
  25. const double epsilon)
  26. {
  27. using namespace std;
  28. //// build collapse map
  29. int n = V.rows();
  30. I = Eigen::Matrix<typename DerivedF::Scalar, Eigen::Dynamic, 1>(n);
  31. I[0] = 0;
  32. bool *VISITED = new bool[n];
  33. for (int i =0; i <n; ++i)
  34. VISITED[i] = false;
  35. NV.resize(n,V.cols());
  36. int count = 0;
  37. Eigen::VectorXd d(n);
  38. for (int i =0; i <n; ++i)
  39. {
  40. if(!VISITED[i])
  41. {
  42. NV.row(count) = V.row(i);
  43. I[i] = count;
  44. VISITED[i] = true;
  45. for (int j = i+1; j <n; ++j)
  46. {
  47. if((V.row(j) - V.row(i)).norm() < epsilon)
  48. {
  49. VISITED[j] = true;
  50. I[j] = count;
  51. }
  52. }
  53. count ++;
  54. }
  55. }
  56. NV.conservativeResize ( count , Eigen::NoChange );
  57. count = 0;
  58. std::vector<typename DerivedF::Scalar> face;
  59. NF.resizeLike(F);
  60. for (int i =0; i <F.rows(); ++i)
  61. {
  62. face.clear();
  63. for (int j = 0; j< F.cols(); ++j)
  64. if(std::find(face.begin(), face.end(), I[F(i,j)]) == face.end())
  65. face.push_back(I[F(i,j)]);
  66. if (face.size() == size_t(F.cols()))
  67. {
  68. for (unsigned j = 0; j< F.cols(); ++j)
  69. NF(count,j) = face[j];
  70. count ++;
  71. }
  72. }
  73. NF.conservativeResize ( count , Eigen::NoChange );
  74. delete [] VISITED;
  75. }
  76. #ifdef IGL_STATIC_LIBRARY
  77. // Explicit template instantiation
  78. template void igl::remove_duplicates<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<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> >&, Eigen::Matrix<Eigen::Matrix<int, -1, -1, 0, -1, -1>::Scalar, -1, 1, 0, -1, 1>&, double);
  79. template void igl::remove_duplicates<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&, Eigen::Matrix<Eigen::Matrix<int, -1, 3, 1, -1, 3>::Scalar, -1, 1, 0, -1, 1>&, double);
  80. #endif