relabel_small_immersed_cells.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 Qingnan Zhou <qnzhou@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. //
  9. #include "relabel_small_immersed_cells.h"
  10. #include "../../centroid.h"
  11. #include "assign_scalar.h"
  12. #include "cell_adjacency.h"
  13. #include <vector>
  14. template<
  15. typename DerivedV,
  16. typename DerivedF,
  17. typename DerivedP,
  18. typename DerivedC,
  19. typename FT,
  20. typename DerivedW>
  21. IGL_INLINE void igl::copyleft::cgal::relabel_small_immersed_cells(
  22. const Eigen::PlainObjectBase<DerivedV>& V,
  23. const Eigen::PlainObjectBase<DerivedF>& F,
  24. const size_t num_patches,
  25. const Eigen::PlainObjectBase<DerivedP>& P,
  26. const size_t num_cells,
  27. const Eigen::PlainObjectBase<DerivedC>& C,
  28. const FT vol_threashold,
  29. Eigen::PlainObjectBase<DerivedW>& W)
  30. {
  31. const size_t num_vertices = V.rows();
  32. const size_t num_faces = F.rows();
  33. typedef std::tuple<typename DerivedC::Scalar, bool, size_t> CellConnection;
  34. std::vector<std::set<CellConnection> > cell_adj;
  35. igl::copyleft::cgal::cell_adjacency(C, num_cells, cell_adj);
  36. Eigen::MatrixXd VV(V.rows(), V.cols());
  37. for (size_t i=0; i<num_vertices; i++) {
  38. igl::copyleft::cgal::assign_scalar(V(i,0), VV(i,0));
  39. igl::copyleft::cgal::assign_scalar(V(i,1), VV(i,1));
  40. igl::copyleft::cgal::assign_scalar(V(i,2), VV(i,2));
  41. }
  42. auto compute_cell_volume = [&](size_t cell_id) {
  43. std::vector<short> is_involved(num_patches, 0);
  44. for (size_t i=0; i<num_patches; i++) {
  45. if (C(i,0) == cell_id) {
  46. // cell is on positive side of patch i.
  47. is_involved[i] = 1;
  48. }
  49. if (C(i,1) == cell_id) {
  50. // cell is on negative side of patch i.
  51. is_involved[i] = -1;
  52. }
  53. }
  54. std::vector<size_t> involved_positive_faces;
  55. std::vector<size_t> involved_negative_faces;
  56. for (size_t i=0; i<num_faces; i++) {
  57. switch (is_involved[P[i]]) {
  58. case 1:
  59. involved_negative_faces.push_back(i);
  60. break;
  61. case -1:
  62. involved_positive_faces.push_back(i);
  63. break;
  64. }
  65. }
  66. const size_t num_positive_faces = involved_positive_faces.size();
  67. const size_t num_negative_faces = involved_negative_faces.size();
  68. DerivedF selected_faces(num_positive_faces + num_negative_faces, 3);
  69. for (size_t i=0; i<num_positive_faces; i++) {
  70. selected_faces.row(i) = F.row(involved_positive_faces[i]);
  71. }
  72. for (size_t i=0; i<num_negative_faces; i++) {
  73. selected_faces.row(num_positive_faces+i) =
  74. F.row(involved_negative_faces[i]).reverse();
  75. }
  76. Eigen::VectorXd c(3);
  77. double vol;
  78. igl::centroid(VV, selected_faces, c, vol);
  79. return vol;
  80. };
  81. std::vector<typename DerivedV::Scalar> cell_volumes(num_cells);
  82. for (size_t i=0; i<num_cells; i++) {
  83. cell_volumes[i] = compute_cell_volume(i);
  84. }
  85. std::vector<typename DerivedW::Scalar> cell_values(num_cells);
  86. for (size_t i=0; i<num_faces; i++) {
  87. cell_values[C(P[i], 0)] = W(i, 0);
  88. cell_values[C(P[i], 1)] = W(i, 1);
  89. }
  90. for (size_t i=1; i<num_cells; i++) {
  91. std::cout << cell_volumes[i] << std::endl;
  92. if (cell_volumes[i] >= vol_threashold) continue;
  93. std::set<typename DerivedW::Scalar> neighbor_values;
  94. const auto neighbors = cell_adj[i];
  95. for (const auto& entry : neighbors) {
  96. const auto& j = std::get<0>(entry);
  97. neighbor_values.insert(cell_values[j]);
  98. }
  99. // If cell i is immersed, assign its value to be the immersed value.
  100. if (neighbor_values.size() == 1) {
  101. cell_values[i] = *neighbor_values.begin();
  102. }
  103. }
  104. for (size_t i=0; i<num_faces; i++) {
  105. W(i,0) = cell_values[C(P[i], 0)];
  106. W(i,1) = cell_values[C(P[i], 1)];
  107. }
  108. }