in code/cpp/tools/scene_annotation_tool/main.cpp [514:680]
void load_scene(std::string scene_dir) {
if (g_scene_loaded) {
unload_scene();
}
// TODO: use portable paths
auto vertices_file = scene_dir + "/mesh_vertices.hdf5";
auto faces_vi_file = scene_dir + "/mesh_faces_vi.hdf5";
auto faces_oi_file = scene_dir + "/mesh_faces_oi.hdf5";
auto mesh_objects_file = scene_dir + "/metadata_objects.csv";
auto metadata_scene_annotation_tool_log_file = scene_dir + "/metadata_scene_annotation_tool.log";
if (!filesystem_exists(vertices_file) || !filesystem_exists(faces_vi_file) || !filesystem_exists(faces_oi_file) || !filesystem_exists(mesh_objects_file)) {
std::cout << "[HYPERSIM: SCENE_ANNOTATION_TOOL] Can't find mesh files in " + scene_dir + "..." << std::endl;
return;
}
//
// load input data
//
g_vertices_orig.load(vertices_file, arma::hdf5_binary_trans);
g_faces_vi_orig.load(faces_vi_file, arma::hdf5_binary_trans);
g_faces_oi_orig.load(faces_oi_file, arma::hdf5_binary_trans);
assert(g_vertices_orig.n_cols == 3);
assert(g_faces_vi_orig.n_cols == 3);
assert(g_faces_vi_orig.n_rows == g_faces_oi_orig.n_elem);
assert(arma::all(arma::vectorise(g_faces_vi_orig) >= 0));
assert(arma::all(arma::vectorise(g_faces_vi_orig) < g_vertices_orig.n_rows));
g_vertices_curr = g_vertices_orig;
g_faces_vi_curr = g_faces_vi_orig;
g_faces_oi_curr = g_faces_oi_orig;
std::ifstream fs(mesh_objects_file);
std::string line;
std::getline(fs, line); // get csv header
assert(fs);
while (std::getline(fs, line)) {
g_mesh_objects.push_back(line);
}
assert(arma::all(g_faces_oi_orig >= 0));
assert(arma::all(g_faces_oi_orig < g_mesh_objects.size()));
// create descs
g_rng = std::mt19937(0);
g_semantic_instance_descs = {};
g_semantic_instance_counter = 0;
g_semantic_instance_id = create_new_semantic_instance_segmentation_id();
g_updated_semantic_instance_id = true;
//
// initialize Embree state, segmentation state, viewer state
//
initialize_segmentation_state(g_segmentation_state_prev);
initialize_segmentation_state(g_segmentation_state_curr);
auto initialized_embree_segmentation_viewer_state = false;
if (g_decimate_mesh_on_load) {
auto prefer_remove_small_vertices = true;
auto prefer_remove_distant_vertices = false;
auto remove_orphaned_vertices = true;
initialized_embree_segmentation_viewer_state = remove_vertices_and_faces(prefer_remove_small_vertices, prefer_remove_distant_vertices, remove_orphaned_vertices);
}
if (!initialized_embree_segmentation_viewer_state) {
initialize_embree_state();
initialize_derived_segmentation_state(g_segmentation_state_prev);
initialize_derived_segmentation_state(g_segmentation_state_curr);
update_derived_segmentation_state();
clear_viewer_mesh();
set_viewer_mesh();
set_viewer_mesh_colors();
}
//
// roughly fit view to scene extent
//
int width_window, height_window;
glfwGetFramebufferSize(g_viewer.window, &width_window, &height_window);
// min, max, mean along columns then transpose to column vectors
arma::vec vertices_min = arma::min(g_vertices_curr, 0).t();
arma::vec vertices_max = arma::max(g_vertices_curr, 0).t();
arma::vec vertices_mean = arma::mean(g_vertices_curr, 0).t();
arma::vec vertices_half_extent = (vertices_max - vertices_min) / 2.0;
arma::vec vertices_center = vertices_min + vertices_half_extent;
auto vertices_half_extent_max = arma::max(vertices_half_extent);
auto k = 0.8; // mesh should occupy this fraction of fov
auto fov_y = g_viewer.core().camera_view_angle * (igl::PI/180.0);
auto fov_x = 2.0 * std::atan(width_window * std::tan(fov_y/2) / height_window);
auto fov = k*std::min(fov_x, fov_y);
auto d = vertices_half_extent_max / std::tan(fov/2.0);
arma::vec look_at_dir = arma::vec({-1,-1,-1}) / arma::norm(arma::vec({-1,-1,-1}));
arma::vec eye = vertices_center - d*look_at_dir;
// g_viewer.core().camera_center << vertices_center(0), vertices_center(1), vertices_center(2);
// g_viewer.core().camera_eye << eye(0), eye(1), eye(2);
// use mean vertex position in case there are lots of low-polygon objects that are far away from the interesting part of the scene
g_viewer.core().camera_center << vertices_mean(0), vertices_mean(1), vertices_mean(2);
g_viewer.core().camera_eye << eye(0), eye(1), eye(2);
g_viewer.core().camera_dfar = 2.0*d;
//
// initialize tool state
//
g_scene_dir = scene_dir;
g_scene_loaded = true;
g_semantic_id = 1;
g_tool = TOOL_RECTANGLE;
g_erase_mode = false;
g_assign_unique_semantic_instance_ids_to_each_mesh_object = false;
g_can_undo = false;
g_can_redo = false;
g_segmentation_layer = SEGMENTATION_LAYER_SEMANTIC;
g_prefer_select_faces_by_mode = PREFER_SELECT_FACES_BY_MODE_OBJECT_MESH_ID;
g_select_only_null_semantic_instance_id = true;
g_select_only_valid_semantic_instance_id = false;
g_select_only_null_semantic_id = true;
g_select_only_valid_semantic_id = false;
// g_navigation_sensitivity = 1.0f;
// g_max_num_vertices = 15000000;
// g_max_num_faces = 1500000;
// g_face_score_area_half_life = 1.0f;
// g_face_score_distance_half_life = 50.0f;
// g_prefer_remove_small_vertices = true;
// g_prefer_remove_distant_vertices = false;
// g_remove_orphaned_vertices = true;
// g_viewer.core().camera_view_angle = 60.0;
// g_viewer.core().camera_dnear = 1.0;
// g_viewer.core().camera_dfar = 10000.0;
g_viewer.data().show_lines = false;
//
// update log
//
std::ofstream ofs;
std::time_t time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
ofs.open(metadata_scene_annotation_tool_log_file, std::ios::out | std::ios::app);
ofs << "[HYPERSIM: SCENE_ANNOTATION_TOOL] Loaded scene: " << std::ctime(&time);
ofs.close();
std::cout << "[HYPERSIM: SCENE_ANNOTATION_TOOL] Loaded scene from " + scene_dir + "..." << std::endl;
}