Skip to content

Commit 21cc7b9

Browse files
authored
Merge pull request #868 from wildmeshing/dzint/tet_remeshing
Dzint/tet remeshing
2 parents eab2761 + 5cb273d commit 21cc7b9

File tree

21 files changed

+680
-159
lines changed

21 files changed

+680
-159
lines changed

CMakeLists.txt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,13 @@ target_link_libraries(wildmeshing_toolkit PUBLIC
126126

127127
if(MSVC)
128128
target_compile_options(wildmeshing_toolkit PUBLIC /MP)
129-
target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELWITHDEBINFO>:/GL>)
130-
target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELWITHDEBINFO>:/LTCG>)
131-
target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELWITHDEBINFO>:/Ob2>) # inline whenever suitable
132-
target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELWITHDEBINFO>:/Ot>) # favor faster code over binary size
133-
target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELEASE>:/GL>)
134-
target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELEASE>:/LTCG>)
135-
target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELEASE>:/Ot>)
129+
# target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELWITHDEBINFO>:/GL>)
130+
# target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELWITHDEBINFO>:/LTCG>)
131+
# target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELWITHDEBINFO>:/Ob2>) # inline whenever suitable
132+
# target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELWITHDEBINFO>:/Ot>) # favor faster code over binary size
133+
# target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELEASE>:/GL>)
134+
# target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELEASE>:/LTCG>)
135+
# target_compile_options(wildmeshing_toolkit PUBLIC $<$<CONFIG:RELEASE>:/Ot>)
136136
target_compile_definitions(wildmeshing_toolkit PUBLIC _SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS)
137137
endif()
138138

cmake/recipes/libigl.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ CPMAddPackage(
1212
GIT_TAG 3ea7f9480967fcf6bf02ce9b993c0ea6d2fc45f6
1313
OPTIONS
1414
LIBIGL_PREDICATES ON
15+
LIBIGL_COPYLEFT_TETGEN ON
1516
)
1617
# include(eigen)
1718
FetchContent_MakeAvailable(libigl)

components/image_simulation/wmtk/components/image_simulation/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ target_link_libraries(wmtk_${COMPONENT_NAME} PUBLIC
4545
wmtk::sec_lib
4646
VolumeRemesher::VolumeRemesher
4747
jse::jse
48+
igl_copyleft::tetgen
4849
)
4950

5051
######################

components/image_simulation/wmtk/components/image_simulation/EmbedSurface.cpp

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <igl/is_vertex_manifold.h>
66
#include <igl/remove_duplicate_vertices.h>
77
#include <igl/remove_unreferenced.h>
8+
#include <igl/copyleft/tetgen/tetrahedralize.h>
89
// igl must be included BEFORE VolumeRemesher
910
#include <VolumeRemesher/embed.h>
1011
#include <VolumeRemesher/numerics.h>
@@ -784,6 +785,8 @@ void EmbedSurface::remove_duplicates(const double eps)
784785

785786
bool EmbedSurface::embed_surface()
786787
{
788+
logger().info("Embed with VolumeInsertion");
789+
787790
std::shared_ptr<SampleEnvelope> ptr_env;
788791
{
789792
const auto v_simplified = V_surf_to_vector();
@@ -838,6 +841,142 @@ bool EmbedSurface::embed_surface()
838841
return all_rounded;
839842
}
840843

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+
841980
void EmbedSurface::consolidate()
842981
{
843982
std::map<size_t, size_t> old2new;

components/image_simulation/wmtk/components/image_simulation/EmbedSurface.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ class EmbedSurface
110110

111111
bool embed_surface();
112112

113+
bool embed_surface_tetgen();
114+
113115
/**
114116
* @brief Remove unreferenced vertices.
115117
*/

components/image_simulation/wmtk/components/image_simulation/ImageSimulationMesh.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ std::tuple<double, double> ImageSimulationMesh::local_operations(
121121
std::tuple<double, double> energy;
122122

123123
auto sanity_checks = [this]() {
124+
if (!m_params.perform_sanity_checks) {
125+
return;
126+
}
124127
logger().info("Perform sanity checks...");
125128
const auto faces = get_faces_by_condition([](auto& f) { return f.m_is_surface_fs; });
126129
for (const auto& verts : faces) {
@@ -694,9 +697,8 @@ std::vector<std::array<size_t, 3>> ImageSimulationMesh::get_faces_by_condition(
694697
if (cond(m_face_attribute[fid])) {
695698
auto tid = fid / 4, lid = fid % 4;
696699
auto verts = get_face_vertices(f);
697-
res.emplace_back(
698-
std::array<size_t, 3>{
699-
{verts[0].vid(*this), verts[1].vid(*this), verts[2].vid(*this)}});
700+
res.emplace_back(std::array<size_t, 3>{
701+
{verts[0].vid(*this), verts[1].vid(*this), verts[2].vid(*this)}});
700702
}
701703
}
702704
return res;
@@ -1133,6 +1135,9 @@ void ImageSimulationMesh::write_vtu(const std::string& path)
11331135
Eigen::MatrixXd V(vs.size(), 3);
11341136
Eigen::MatrixXi T(tets.size(), 4);
11351137

1138+
Eigen::VectorXd v_sizing_field(vert_capacity());
1139+
v_sizing_field.setZero();
1140+
11361141
Eigen::MatrixXd parts(tets.size(), 1);
11371142
std::vector<MatrixXd> tags(m_tags_count, MatrixXd(tets.size(), 1));
11381143
Eigen::MatrixXd amips(tets.size(), 1);
@@ -1156,6 +1161,7 @@ void ImageSimulationMesh::write_vtu(const std::string& path)
11561161
for (const Tuple& v : vs) {
11571162
const size_t vid = v.vid(*this);
11581163
V.row(vid) = m_vertex_attribute[vid].m_posf;
1164+
v_sizing_field[vid] = m_vertex_attribute[vid].m_sizing_scalar;
11591165
}
11601166

11611167
std::shared_ptr<paraviewo::ParaviewWriter> writer;
@@ -1166,6 +1172,7 @@ void ImageSimulationMesh::write_vtu(const std::string& path)
11661172
writer->add_cell_field(fmt::format("tag_{}", j), tags[j]);
11671173
}
11681174
writer->add_cell_field("quality", amips);
1175+
writer->add_field("sizing_field", v_sizing_field);
11691176
writer->write_mesh(path, V, T);
11701177
}
11711178

components/image_simulation/wmtk/components/image_simulation/Parameters.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ struct Parameters
2222

2323
double stop_energy = 10;
2424

25+
bool perform_sanity_checks = false;
26+
2527
void init(const Vector3d& min_, const Vector3d& max_)
2628
{
2729
box_min = min_;

components/image_simulation/wmtk/components/image_simulation/image_simulation.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,10 @@
66

77
#include <jse/jse.h>
88
#include <wmtk/TetMesh.h>
9-
#include <wmtk/utils/Partitioning.h>
10-
#include <paraviewo/VTUWriter.hpp>
119
#include <wmtk/Types.hpp>
12-
#include <wmtk/envelope/Envelope.hpp>
13-
#include <wmtk/utils/InsertTriangleUtils.hpp>
1410
#include <wmtk/utils/Logger.hpp>
15-
#include <wmtk/utils/ManifoldUtils.hpp>
16-
#include <wmtk/utils/Reader.hpp>
17-
#include <wmtk/utils/io.hpp>
18-
#include <wmtk/utils/partition_utils.hpp>
1911
#include <wmtk/utils/resolve_path.hpp>
2012

21-
#include <sec/ShortestEdgeCollapse.h>
22-
2313
#include "EmbedSurface.hpp"
2414
#include "ImageSimulationMesh.h"
2515
#include "Parameters.h"
@@ -164,7 +154,9 @@ void image_simulation(nlohmann::json json_params)
164154
V_envelope = image_mesh.V_surface();
165155
F_envelope = image_mesh.F_surface();
166156

167-
const bool all_rounded = image_mesh.embed_surface();
157+
// const bool all_rounded = image_mesh.embed_surface();
158+
const bool all_rounded = json_params["use_tetgen"] ? image_mesh.embed_surface_tetgen()
159+
: image_mesh.embed_surface();
168160
image_mesh.consolidate();
169161

170162
if (write_vtu) {

0 commit comments

Comments
 (0)