removeDuplicates.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. //
  2. // removeDuplicates.h
  3. // Preview3D
  4. //
  5. // Created by Olga Diamanti on 17/11/11.
  6. // Copyright (c) 2011 __MyCompanyName__. All rights reserved.
  7. //
  8. #ifndef RemoveDuplicates_h
  9. #define RemoveDuplicates_h
  10. #include <Eigen/Core>
  11. namespace igl
  12. {
  13. // [ NV, NF ] = removeDuplicates( V,F,epsilon )
  14. // Merge the duplicate vertices from V, fixing the topology accordingly
  15. //
  16. // Input:
  17. // V,F: mesh description
  18. // epsilon: minimal distance to consider two vertices identical
  19. //
  20. // Output:
  21. // NV, NF: new mesh without duplicate vertices
  22. template <typename T>
  23. inline void removeDuplicates(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V, const Eigen::MatrixXi &F, Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV, Eigen::MatrixXi &NF, Eigen::VectorXi &I, const double epsilon = 2.2204e-15);
  24. }
  25. // Implementation
  26. template <typename T>
  27. inline void igl::removeDuplicates(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &V, const Eigen::MatrixXi &F, Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &NV, Eigen::MatrixXi &NF, Eigen::VectorXi &I, const double epsilon)
  28. {
  29. assert (F.cols() == 3);
  30. //// build collapse map
  31. int n = V.rows();
  32. I = Eigen::VectorXi (n);
  33. I[0] = 0;
  34. bool *VISITED = new bool[n];
  35. for (int i =0; i <n; ++i)
  36. VISITED[i] = false;
  37. NV = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>(n,V.cols());
  38. int count = 0;
  39. Eigen::VectorXd d(n);
  40. for (int i =0; i <n; ++i)
  41. {
  42. if(!VISITED[i])
  43. {
  44. NV.row(count) = V.row(i);
  45. I[i] = count;
  46. VISITED[i] = true;
  47. for (int j = i+1; j <n; ++j)
  48. {
  49. if((V.row(j) - V.row(i)).norm() < epsilon)
  50. {
  51. VISITED[j] = true;
  52. I[j] = count;
  53. }
  54. }
  55. count ++;
  56. }
  57. }
  58. NV.conservativeResize ( count , Eigen::NoChange );
  59. count = 0;
  60. NF = Eigen::MatrixXi(F.rows(),3);
  61. for (int i =0; i <F.rows(); ++i)
  62. {
  63. int v0 = I[F(i,0)];
  64. int v1 = I[F(i,1)];
  65. int v2 = I[F(i,2)];
  66. if ( (v0 != v1) && (v2 != v1) && (v0 != v2) )
  67. NF.row(count++) << v0, v1, v2;
  68. }
  69. NF.conservativeResize ( count , Eigen::NoChange );
  70. delete [] VISITED;
  71. }
  72. #endif