flood_fill.cpp 2.2 KB

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