upsample.cpp 3.2 KB

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