flood_fill.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include "flood_fill.h"
  2. #include <limits>
  3. IGL_INLINE void igl::flood_fill(
  4. const Eigen::RowVector3i & res,
  5. Eigen::VectorXd & S)
  6. {
  7. using namespace Eigen;
  8. using namespace std;
  9. const auto flood = [&res,&S] (
  10. const int xi,
  11. const int yi,
  12. const int zi,
  13. const int signed_xi,
  14. const int signed_yi,
  15. const int signed_zi,
  16. const double s)
  17. {
  18. // flood fill this value back on this row
  19. for(int bxi = xi;signed_xi<--bxi;)
  20. {
  21. S(bxi+res(0)*(yi + res(1)*zi)) = s;
  22. }
  23. // flood fill this value back on any previous rows
  24. for(int byi = yi;signed_yi<--byi;)
  25. {
  26. for(int xi = 0;xi<res(0);xi++)
  27. {
  28. S(xi+res(0)*(byi + res(1)*zi)) = s;
  29. }
  30. }
  31. // flood fill this value back on any previous "sheets"
  32. for(int bzi = zi;signed_zi<--bzi;)
  33. {
  34. for(int yi = 0;yi<res(1);yi++)
  35. {
  36. for(int xi = 0;xi<res(0);xi++)
  37. {
  38. S(xi+res(0)*(yi + res(1)*bzi)) = s;
  39. }
  40. }
  41. }
  42. };
  43. int signed_zi = -1;
  44. double s = numeric_limits<double>::quiet_NaN();
  45. for(int zi = 0;zi<res(2);zi++)
  46. {
  47. int signed_yi = -1;
  48. if(zi != 0)
  49. {
  50. s = S(0+res(0)*(0 + res(1)*(zi-1)));
  51. }
  52. for(int yi = 0;yi<res(1);yi++)
  53. {
  54. // index of last signed item on this row
  55. int signed_xi = -1;
  56. if(yi != 0)
  57. {
  58. s = S(0+res(0)*(yi-1 + res(1)*zi));
  59. }
  60. for(int xi = 0;xi<res(0);xi++)
  61. {
  62. int i = xi+res(0)*(yi + res(1)*zi);
  63. if(S(i)!=S(i))
  64. {
  65. if(s == s)
  66. {
  67. S(i) = s;
  68. }
  69. continue;
  70. }
  71. s = S(i);
  72. flood(xi,yi,zi,signed_xi,signed_yi,signed_zi,s);
  73. // remember this position
  74. signed_xi = xi;
  75. signed_yi = yi;
  76. signed_zi = zi;
  77. }
  78. }
  79. }
  80. }