|
5 | 5 | #include <igl/is_vertex_manifold.h> |
6 | 6 | #include <igl/remove_duplicate_vertices.h> |
7 | 7 | #include <igl/remove_unreferenced.h> |
| 8 | +#include <igl/copyleft/tetgen/tetrahedralize.h> |
8 | 9 | // igl must be included BEFORE VolumeRemesher |
9 | 10 | #include <VolumeRemesher/embed.h> |
10 | 11 | #include <VolumeRemesher/numerics.h> |
@@ -784,6 +785,8 @@ void EmbedSurface::remove_duplicates(const double eps) |
784 | 785 |
|
785 | 786 | bool EmbedSurface::embed_surface() |
786 | 787 | { |
| 788 | + logger().info("Embed with VolumeInsertion"); |
| 789 | + |
787 | 790 | std::shared_ptr<SampleEnvelope> ptr_env; |
788 | 791 | { |
789 | 792 | const auto v_simplified = V_surf_to_vector(); |
@@ -838,6 +841,142 @@ bool EmbedSurface::embed_surface() |
838 | 841 | return all_rounded; |
839 | 842 | } |
840 | 843 |
|
| 844 | +bool EmbedSurface::embed_surface_tetgen() |
| 845 | +{ |
| 846 | + logger().info("Embed with TetGen"); |
| 847 | + |
| 848 | + std::shared_ptr<SampleEnvelope> ptr_env; |
| 849 | + { |
| 850 | + const auto v_simplified = V_surf_to_vector(); |
| 851 | + |
| 852 | + std::vector<Eigen::Vector3i> tempF(m_F_surface.rows()); |
| 853 | + for (size_t i = 0; i < tempF.size(); ++i) { |
| 854 | + tempF[i] = m_F_surface.row(i); |
| 855 | + } |
| 856 | + ptr_env = std::make_shared<SampleEnvelope>(); |
| 857 | + ptr_env->init(v_simplified, tempF, 0.5); |
| 858 | + } |
| 859 | + |
| 860 | + Eigen::MatrixXd V_in; |
| 861 | + Eigen::MatrixXi F_in; |
| 862 | + { |
| 863 | + const Vector3d vertices_max = m_V_surface.colwise().maxCoeff(); |
| 864 | + const Vector3d vertices_min = m_V_surface.colwise().minCoeff(); |
| 865 | + const double diag = (vertices_max - vertices_min).norm(); |
| 866 | + |
| 867 | + // bbox |
| 868 | + double delta = diag / 15.0; |
| 869 | + const Vector3d box_min( |
| 870 | + vertices_min[0] - delta, |
| 871 | + vertices_min[1] - delta, |
| 872 | + vertices_min[2] - delta); |
| 873 | + const Vector3d box_max( |
| 874 | + vertices_max[0] + delta, |
| 875 | + vertices_max[1] + delta, |
| 876 | + vertices_max[2] + delta); |
| 877 | + |
| 878 | + |
| 879 | + // add corners of domain |
| 880 | + std::vector<Vector3d> points(8); |
| 881 | + for (int i = 0; i < 8; i++) { |
| 882 | + Vector3d& p = points[i]; |
| 883 | + std::bitset<sizeof(int) * 8> a(i); |
| 884 | + for (int j = 0; j < 3; j++) { |
| 885 | + if (a.test(j)) { |
| 886 | + p[j] = box_max[j]; |
| 887 | + } else { |
| 888 | + p[j] = box_min[j]; |
| 889 | + } |
| 890 | + } |
| 891 | + } |
| 892 | + |
| 893 | + const double voxel_resolution = diag / 20.0; |
| 894 | + std::array<int, 3> N; // number of grid points per dimension |
| 895 | + std::array<double, 3> h; // distance between grid points per dimension |
| 896 | + for (int i = 0; i < 3; i++) { |
| 897 | + const double D = box_max[i] - box_min[i]; |
| 898 | + N[i] = (D / voxel_resolution) + 1; |
| 899 | + h[i] = D / N[i]; |
| 900 | + } |
| 901 | + |
| 902 | + std::array<std::vector<double>, 3> ds; |
| 903 | + for (int i = 0; i < 3; i++) { |
| 904 | + ds[i].push_back(box_min[i]); |
| 905 | + for (int j = 0; j < N[i] - 1; j++) { |
| 906 | + ds[i].push_back(box_min[i] + h[i] * (j + 1)); |
| 907 | + } |
| 908 | + ds[i].push_back(box_max[i]); |
| 909 | + } |
| 910 | + |
| 911 | + const double min_dis = voxel_resolution * voxel_resolution / 4; |
| 912 | + // double min_dis = state.target_edge_len * state.target_edge_len;//epsilon*2 |
| 913 | + for (int i = 0; i < ds[0].size(); i++) { |
| 914 | + for (int j = 0; j < ds[1].size(); j++) { |
| 915 | + for (int k = 0; k < ds[2].size(); k++) { |
| 916 | + if ((i == 0 || i == ds[0].size() - 1) && (j == 0 || j == ds[1].size() - 1) && |
| 917 | + (k == 0 || k == ds[2].size() - 1)) { |
| 918 | + continue; |
| 919 | + } |
| 920 | + const Vector3d p(ds[0][i], ds[1][j], ds[2][k]); |
| 921 | + |
| 922 | + Eigen::Vector3d n; |
| 923 | + const double sqd = ptr_env->nearest_point(p, n); |
| 924 | + |
| 925 | + if (sqd < min_dis) { |
| 926 | + continue; |
| 927 | + } |
| 928 | + points.emplace_back(ds[0][i], ds[1][j], ds[2][k]); |
| 929 | + } |
| 930 | + } |
| 931 | + } |
| 932 | + |
| 933 | + |
| 934 | + V_in.resize(m_V_surface.rows() + points.size(), 3); |
| 935 | + V_in.block(0, 0, m_V_surface.rows(), 3) = m_V_surface; |
| 936 | + for (size_t i = 0; i < points.size(); ++i) { |
| 937 | + V_in.row(m_V_surface.rows() + i) = points[i]; |
| 938 | + } |
| 939 | + std::array<size_t, 8> p; |
| 940 | + for (size_t i = 0; i < p.size(); ++i) { |
| 941 | + p[i] = m_V_surface.rows() + i; |
| 942 | + } |
| 943 | + |
| 944 | + |
| 945 | + F_in = m_F_surface; |
| 946 | + // F_in.resize(m_F_surface.rows() + 12, 3); |
| 947 | + // F_in.block(0, 0, m_F_surface.rows(), 3) = m_F_surface; |
| 948 | + // F_in.row(m_F_surface.rows() + 0) = Vector3i(p[0], p[1], p[2]); |
| 949 | + // F_in.row(m_F_surface.rows() + 1) = Vector3i(p[1], p[3], p[2]); |
| 950 | + // F_in.row(m_F_surface.rows() + 2) = Vector3i(p[0], p[5], p[1]); |
| 951 | + // F_in.row(m_F_surface.rows() + 3) = Vector3i(p[0], p[4], p[5]); |
| 952 | + // F_in.row(m_F_surface.rows() + 4) = Vector3i(p[0], p[6], p[4]); |
| 953 | + // F_in.row(m_F_surface.rows() + 5) = Vector3i(p[0], p[2], p[6]); |
| 954 | + // F_in.row(m_F_surface.rows() + 6) = Vector3i(p[7], p[3], p[2]); |
| 955 | + // F_in.row(m_F_surface.rows() + 7) = Vector3i(p[7], p[2], p[6]); |
| 956 | + // F_in.row(m_F_surface.rows() + 8) = Vector3i(p[7], p[6], p[4]); |
| 957 | + // F_in.row(m_F_surface.rows() + 9) = Vector3i(p[7], p[4], p[5]); |
| 958 | + // F_in.row(m_F_surface.rows() + 10) = Vector3i(p[7], p[5], p[1]); |
| 959 | + // F_in.row(m_F_surface.rows() + 11) = Vector3i(p[7], p[1], p[3]); |
| 960 | + } |
| 961 | + |
| 962 | + MatrixXi TF; |
| 963 | + |
| 964 | + int ret = igl::copyleft::tetgen::tetrahedralize(V_in, F_in, "pc", m_V_emb, m_T_emb, TF); |
| 965 | + if (ret != 0) { |
| 966 | + log_and_throw_error("TetGen returned with {}", ret); |
| 967 | + } |
| 968 | + |
| 969 | + m_V_emb_r.resizeLike(m_V_emb); |
| 970 | + for (int i = 0; i < m_V_emb.rows(); ++i) { |
| 971 | + m_V_emb_r.row(i) = to_rational(m_V_emb.row(i)); |
| 972 | + } |
| 973 | + |
| 974 | + // add tags |
| 975 | + tag_tets_from_images(m_img_datas, m_xyz2ijk, m_V_emb, m_T_emb, m_T_tags); |
| 976 | + |
| 977 | + return true; |
| 978 | +} |
| 979 | + |
841 | 980 | void EmbedSurface::consolidate() |
842 | 981 | { |
843 | 982 | std::map<size_t, size_t> old2new; |
|
0 commit comments