lipschitz_octree.cpp 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2025 Alec Jacobson <[email protected]>
  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 "lipschitz_octree.h"
  9. #include "lipschitz_octree_prune.h"
  10. #include "find.h"
  11. #include "matlab_format.h"
  12. #include <cassert>
  13. #include <iostream>
  14. template <
  15. bool batched,
  16. typename Derivedorigin,
  17. typename Func,
  18. typename Derivedijk
  19. >
  20. IGL_INLINE void igl::lipschitz_octree(
  21. const Eigen::MatrixBase<Derivedorigin> & origin,
  22. const typename Derivedorigin::Scalar h0,
  23. const int max_depth,
  24. const Func & udf,
  25. Eigen::PlainObjectBase<Derivedijk> & ijk_out)
  26. {
  27. using Scalar = typename Derivedorigin::Scalar;
  28. using RowVectorS3 = Eigen::Matrix<Scalar,1,3>;
  29. using MatrixSX8R = Eigen::Matrix<Scalar,Eigen::Dynamic,8,Eigen::RowMajor>;
  30. using MatrixiX3R = Eigen::Matrix<int,Eigen::Dynamic,3,Eigen::RowMajor>;
  31. // static assert to ensure that Derivedorigin is a vector and the
  32. // non-singleton dimension is 3 or Eigen::Dynamic
  33. static_assert(
  34. (Derivedorigin::RowsAtCompileTime == 1 && (
  35. Derivedorigin::ColsAtCompileTime == 3 ||
  36. Derivedorigin::ColsAtCompileTime == Eigen::Dynamic)) ||
  37. (Derivedorigin::ColsAtCompileTime == 1 && (
  38. Derivedorigin::RowsAtCompileTime == 3 ||
  39. Derivedorigin::RowsAtCompileTime == Eigen::Dynamic)),
  40. "Derivedorigin must be a vector with 3 or Eigen::Dynamic dimensions");
  41. // dynamic assert that the origin is a 3D vector
  42. assert((origin.rows() == 3 || origin.cols() == 3) && origin.size() == 3 &&
  43. "origin must be a 3D vector");
  44. MatrixiX3R ijk(1,3);
  45. ijk<<0,0,0;
  46. for(int depth = 0;depth<=max_depth;depth++)
  47. {
  48. if(ijk.rows() == 0)
  49. {
  50. // no more cells to refine
  51. break;
  52. }
  53. const Scalar h = h0 / (1 << depth);
  54. MatrixiX3R ijk_next;
  55. MatrixiX3R ijk_maybe;
  56. igl::lipschitz_octree_prune<batched>(origin,h0,depth,udf,ijk,ijk_maybe);
  57. if(depth == max_depth)
  58. {
  59. // sad copy
  60. ijk_out = ijk_maybe.template cast<typename Derivedijk::Scalar>();
  61. return;
  62. }else
  63. {
  64. const MatrixiX3R ijk_maybe_2 = ijk_maybe * 2;
  65. ijk_next.resize(ijk_maybe_2.rows()*8,3);
  66. for(int c = 0;c<ijk_maybe_2.rows();c++)
  67. {
  68. for(int i = 0;i<8;i++)
  69. {
  70. const int k = i;
  71. ijk_next.row(c*8+k) =
  72. ijk_maybe_2.row(c) +
  73. // This order shouldn't really matter, though it seems nice if it
  74. // matches above.
  75. Eigen::RowVector3i((i&2) ? 1 : 0, (i&4) ? 1 : 0, (i&1) ? 1 : 0);
  76. }
  77. }
  78. }
  79. if(depth == max_depth)
  80. {
  81. break;
  82. }
  83. ijk = ijk_next;
  84. }
  85. assert(false && "Should never reach here");
  86. }
  87. #ifdef IGL_STATIC_LIBRARY
  88. // Explicit template instantiation
  89. template void igl::lipschitz_octree<false,Eigen::Matrix<double, 1, 3, 1, 1, 3>, std::function<double (Eigen::Matrix<double, 1, 3, 1, 1, 3> const&)>, Eigen::Matrix<int, -1, 3, 1, -1, 3>>(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3>> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3>::Scalar, int, std::function<double (Eigen::Matrix<double, 1, 3, 1, 1, 3> const&)> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3>>&);
  90. template void igl::lipschitz_octree<true, Eigen::Matrix<double, 1, 3, 1, 1, 3>, std::function<Eigen::Matrix<double, -1, 1, 0, -1, 1> (Eigen::Matrix<double, -1, 3, 1, -1, 3> const&)>, Eigen::Matrix<int, -1, 3, 1, -1, 3>>(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3>> const&, Eigen::Matrix<double, 1, 3, 1, 1, 3>::Scalar, int, std::function<Eigen::Matrix<double, -1, 1, 0, -1, 1> (Eigen::Matrix<double, -1, 3, 1, -1, 3> const&)> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3>>&);
  91. #endif