void load_scene()

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;
}