upsample.cpp 2.4 KB

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