1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 | /*
* This file is part of
* Surface Maps via Adaptive Triangulations
* (https://github.com/patr-schm/surface-maps-via-adaptive-triangulations)
* and is released under the MIT license.
*
* Authors: Patrick Schmidt, Dörte Pieper
*/
#include <SurfaceMaps/Init.hh>
#include <SurfaceMaps/Utils/IO.hh>
#include <SurfaceMaps/Viewer/MeshView.hh>
#include <SurfaceMaps/AdaptiveTriangulations/Helpers.hh>
#include <SurfaceMaps/AdaptiveTriangulations/Visualization.hh>
#include <SurfaceMaps/AdaptiveTriangulations/DistortionHeatmap.hh>
#include <SurfaceMaps/AdaptiveTriangulations/InitSphereEmbeddings.hh>
#include <SurfaceMaps/AdaptiveTriangulations/OptimizeCoarseToFine.hh>
#include <SurfaceMaps/AdaptiveTriangulations/OptimizeWithRemeshing.hh>
#include <SurfaceMaps/AdaptiveTriangulations/LiftToSurface.hh>
const bool open_viewer = false; // or write screenshots
namespace SurfaceMaps
{
void run_pair(
const int _handB_num)
{
// Create output directory
fs::path output_dir = OUTPUT_PATH / "initialization_hands" / ("hand_" + std::to_string(_handB_num));
fs::path screenshot_dir = output_dir / ("screenshots");
fs::create_directories(screenshot_dir);
const fs::path _mesh_path_A = DATA_PATH / "meshes/hand/hand_plain.obj";
const fs::path _mesh_path_B = DATA_PATH / "meshes/hand/hand_vulcan.obj";
const fs::path _landmarks_path_A = DATA_PATH / "meshes/hand/hand_plain.pinned";
const fs::path _landmarks_path_B = DATA_PATH / ("meshes/hand/hand_vulcan_" + std:: to_string(_handB_num) + ".pinned");
const fs::path embedding_path_A = output_dir / "embedding_A.obj";
const fs::path embedding_path_B = output_dir / "embedding_B.obj";
glow::SharedTexture2D texture = read_texture(DATA_PATH / "meshes/hand/hand_plain_texture.png");
// Init map
MapState map_state;
if (!init_map(map_state, { _mesh_path_A, _mesh_path_B }, { _landmarks_path_A, _landmarks_path_B }, { embedding_path_A, embedding_path_B }, false))
return;
// Visualization
auto cam_pos = glow::viewer::camera_transform(tg::pos3(-0.155488f, 0.903014f, 1.873404f), tg::pos3(-0.128843f, 0.788787f, 1.659081f));
double heatmap_max = 100.0;
auto screenshot = [&] (const std::string& prefix)
{
std::vector<TriMesh> lifted_Ts = lifted_meshes_from_mapstate(map_state);
ExternalProperty<FH, Color> colors = compute_distortion_heatmap(lifted_Ts[0], lifted_Ts[1], heatmap_max);
for (int i = 0; i < (int)map_state.meshes_input.size(); ++i)
{
auto sun = gv::config(gv::sun_scale_factor(1.5));
{
// Mesh T
auto cam_config = gv::config(cam_pos);
auto s = screenshot_config(open_viewer, screenshot_dir / (prefix + "_" + pad_integer(i, 2) + ".png"), tg::ivec2(1920, 1080), true);
auto v = gv::view();
view_mesh(map_state.meshes_input[i], Color(1.0, 1.0, 1.0, 0.5));
view_mesh(lifted_Ts[i], Color(1.0, 1.0, 1.0, 1.0));
view_wireframe(lifted_Ts[i], MAGENTA, WidthScreen(0.7));
view_landmarks(lifted_Ts[i], map_state.landmarks_T, WidthScreen(10.0));
}
{
// Texture
auto cam_config = gv::config(cam_pos);
auto s = screenshot_config(open_viewer, screenshot_dir / (prefix + "_" + pad_integer(i, 2) + "_textured.png"), tg::ivec2(1920, 1080), true);
auto v = gv::view();
view_texture_halfedgetexcoords_input(map_state, 0, i, texture);
view_landmarks(lifted_Ts[i], map_state.landmarks_T, WidthScreen(10.0));
}
}
};
ISM_ASSERT(map_state.meshes_input[0].has_halfedge_texcoords2D());
// Algorithm schedule
screenshot("00_init");
landmark_phase(map_state);
screenshot("01_after_landmark");
release_landmarks(map_state);
AdaptiveTriangulationsSettings coarse_settings = coarse_phase_settings();
coarse_settings.w_map = 10.0;
coarse_settings.set_adaptive_tel_params(0.015, 0.001, 100.0);
coarse_settings.max_iterations = 400;
optimize_with_remeshing(map_state, coarse_settings, "");
screenshot("02_after_coarse");
AdaptiveTriangulationsSettings coarse_settings2 = coarse_phase_settings();
coarse_settings2.max_iterations = 200;
optimize_with_remeshing(map_state, coarse_settings2, "");
screenshot("03_after_coarse");
AdaptiveTriangulationsSettings fine_settings = fine_phase_settings(0.0008);
fine_settings.max_iterations = 200;
optimize_with_remeshing(map_state, fine_settings, "");
screenshot("04_after_fine");
// Save lifted T meshes
{
const std::vector<TriMesh> liftedTs = lifted_meshes_from_mapstate(map_state);
write_mesh(liftedTs[0], output_dir / ("T_A.obj"));
write_mesh(liftedTs[1], output_dir / ("T_B.obj"));
}
}
}
int main()
{
glow::glfw::GlfwContext ctx;
using namespace SurfaceMaps;
init_lib_surface_maps();
run_pair(1);
run_pair(3);
run_pair(5);
run_pair(7);
run_pair(8);
return 0;
}
|