upsample.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include "upsample.h"
  2. #include "tt.h"
  3. #include <Eigen/Dense>
  4. // Bug in unsupported/Eigen/SparseExtra needs iostream first
  5. #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
  6. #include <iostream>
  7. #include <unsupported/Eigen/SparseExtra>
  8. template <typename MatV, typename MatF>
  9. IGL_INLINE void igl::upsample( const MatV & V, const MatF & F, MatV & NV, MatF & NF)
  10. {
  11. // Use "in place" wrapper instead
  12. assert(&V != &NV);
  13. assert(&F != &NF);
  14. using namespace igl;
  15. using namespace std;
  16. using namespace Eigen;
  17. MatF FF, FFi;
  18. tt<double>(V,F,FF,FFi);
  19. // TODO: Cache optimization missing from here, it is a mess
  20. // Compute the number and positions of the vertices to insert (on edges)
  21. MatF NI = MatF::Constant(FF.rows(),FF.cols(),-1);
  22. int counter = 0;
  23. for(int i=0;i<FF.rows();++i)
  24. {
  25. for(int j=0;j<3;++j)
  26. {
  27. if(NI(i,j) == -1)
  28. {
  29. NI(i,j) = counter;
  30. if (FF(i,j) != -1) // If it is not a border
  31. NI(FF(i,j),FFi(i,j)) = counter;
  32. ++counter;
  33. }
  34. }
  35. }
  36. int n_odd = V.rows();
  37. int n_even = counter;
  38. // Not sure what this is
  39. //Eigen::DynamicSparseMatrix<double> SUBD(V.rows()+n_even,V.rows());
  40. //SUBD.reserve(15 * (V.rows()+n_even));
  41. // Preallocate NV and NF
  42. NV = MatV(V.rows()+n_even,V.cols());
  43. NF = MatF(F.rows()*4,3);
  44. // Fill the odd vertices position
  45. NV.block(0,0,V.rows(),V.cols()) = V;
  46. // Fill the even vertices position
  47. for(int i=0;i<FF.rows();++i)
  48. {
  49. for(int j=0;j<3;++j)
  50. {
  51. NV.row(NI(i,j) + n_odd) = 0.5 * V.row(F(i,j)) + 0.5 * V.row(F(i,(j+1)%3));
  52. }
  53. }
  54. // Build the new topology (Every face is replaced by four)
  55. for(int i=0; i<F.rows();++i)
  56. {
  57. VectorXi VI(6);
  58. VI << F(i,0), F(i,1), F(i,2), NI(i,0) + n_odd, NI(i,1) + n_odd, NI(i,2) + n_odd;
  59. VectorXi f0(3), f1(3), f2(3), f3(3);
  60. f0 << VI(0), VI(3), VI(5);
  61. f1 << VI(1), VI(4), VI(3);
  62. f2 << VI(3), VI(4), VI(5);
  63. f3 << VI(4), VI(2), VI(5);
  64. NF.row((i*4)+0) = f0;
  65. NF.row((i*4)+1) = f1;
  66. NF.row((i*4)+2) = f2;
  67. NF.row((i*4)+3) = f3;
  68. }
  69. }
  70. template <typename MatV, typename MatF>
  71. IGL_INLINE void igl::upsample( MatV & V,MatF & F)
  72. {
  73. const MatV V_copy = V;
  74. const MatF F_copy = F;
  75. return upsample(V_copy,F_copy,V,F);
  76. }
  77. #ifndef IGL_HEADER_ONLY
  78. // Explicit template specialization
  79. //template void igl::upsample<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::Matrix<double, -1, -1, 0, -1, -1>&, Eigen::Matrix<int, -1, -1, 0, -1, -1>&);
  80. #endif