flood_fill.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. template <typename Derivedres, typename DerivedS>
  11. IGL_INLINE void igl::flood_fill(
  12. const Eigen::MatrixBase<Derivedres>& res,
  13. Eigen::PlainObjectBase<DerivedS> & S)
  14. {
  15. using namespace Eigen;
  16. using namespace std;
  17. typedef typename DerivedS::Scalar Scalar;
  18. const auto flood = [&res,&S] (
  19. const int xi,
  20. const int yi,
  21. const int zi,
  22. const int signed_xi,
  23. const int signed_yi,
  24. const int signed_zi,
  25. const Scalar s)
  26. {
  27. // flood fill this value back on this row
  28. for(int bxi = xi;signed_xi<--bxi;)
  29. {
  30. S(bxi+res(0)*(yi + res(1)*zi)) = s;
  31. }
  32. // flood fill this value back on any previous rows
  33. for(int byi = yi;signed_yi<--byi;)
  34. {
  35. for(int xi = 0;xi<res(0);xi++)
  36. {
  37. S(xi+res(0)*(byi + res(1)*zi)) = s;
  38. }
  39. }
  40. // flood fill this value back on any previous "sheets"
  41. for(int bzi = zi;signed_zi<--bzi;)
  42. {
  43. for(int yi = 0;yi<res(1);yi++)
  44. {
  45. for(int xi = 0;xi<res(0);xi++)
  46. {
  47. S(xi+res(0)*(yi + res(1)*bzi)) = s;
  48. }
  49. }
  50. }
  51. };
  52. int signed_zi = -1;
  53. Scalar s = numeric_limits<Scalar>::quiet_NaN();
  54. for(int zi = 0;zi<res(2);zi++)
  55. {
  56. int signed_yi = -1;
  57. if(zi != 0)
  58. {
  59. s = S(0+res(0)*(0 + res(1)*(zi-1)));
  60. }
  61. for(int yi = 0;yi<res(1);yi++)
  62. {
  63. // index of last signed item on this row
  64. int signed_xi = -1;
  65. if(yi != 0)
  66. {
  67. s = S(0+res(0)*(yi-1 + res(1)*zi));
  68. }
  69. for(int xi = 0;xi<res(0);xi++)
  70. {
  71. int i = xi+res(0)*(yi + res(1)*zi);
  72. if(S(i)!=S(i))
  73. {
  74. if(s == s)
  75. {
  76. S(i) = s;
  77. }
  78. continue;
  79. }
  80. s = S(i);
  81. flood(xi,yi,zi,signed_xi,signed_yi,signed_zi,s);
  82. // remember this position
  83. signed_xi = xi;
  84. signed_yi = yi;
  85. signed_zi = zi;
  86. }
  87. }
  88. }
  89. }
  90. #ifdef IGL_STATIC_LIBRARY
  91. // Explicit template instantiation
  92. // generated by autoexplicit.sh
  93. template void igl::flood_fill<Eigen::Matrix<int, 1, 3, 1, 1, 3>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
  94. // generated by autoexplicit.sh
  95. template void igl::flood_fill<Eigen::Matrix<int, 3, 1, 0, 3, 1>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
  96. // generated by autoexplicit.sh
  97. template void igl::flood_fill<Eigen::Matrix<int, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  98. // generated by autoexplicit.sh
  99. template void igl::flood_fill<Eigen::Matrix<int, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  100. template void igl::flood_fill<Eigen::Matrix<float, 1, 3, 1, 1, 3>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
  101. #endif