예제 #1
0
int main(int argc, char **argv) {
    util::system::print_build_timestamp(argv[0]);
    util::system::register_segfault_handler();

#ifdef RESEARCH
    std::cout << "******************************************************************************" << std::endl
              << " Due to use of the -DRESEARCH=ON compile option, this program is licensed "     << std::endl
              << " for research purposes only. Please pay special attention to the gco license."  << std::endl
              << "******************************************************************************" << std::endl;
#endif

    Timer timer;
    util::WallTimer wtimer;

    Arguments conf;
    try {
        conf = parse_args(argc, argv);
    } catch (std::invalid_argument & ia) {
        std::cerr << ia.what() << std::endl;
        std::exit(EXIT_FAILURE);
    }

    if (!util::fs::dir_exists(util::fs::dirname(conf.out_prefix).c_str())) {
        std::cerr << "Destination directory does not exist!" << std::endl;
        std::exit(EXIT_FAILURE);
    }

    std::cout << "Load and prepare mesh: " << std::endl;
    mve::TriangleMesh::Ptr mesh;
    try {
        mesh = mve::geom::load_ply_mesh(conf.in_mesh);
    } catch (std::exception& e) {
        std::cerr << "\tCould not load mesh: "<< e.what() << std::endl;
        std::exit(EXIT_FAILURE);
    }
    mve::MeshInfo mesh_info(mesh);
    tex::prepare_mesh(&mesh_info, mesh);

    std::cout << "Generating texture views: " << std::endl;
    tex::TextureViews texture_views;
    tex::generate_texture_views(conf.in_scene, &texture_views);

    write_string_to_file(conf.out_prefix + ".conf", conf.to_string());
    timer.measure("Loading");

    std::size_t const num_faces = mesh->get_faces().size() / 3;

    std::cout << "Building adjacency graph: " << std::endl;
    tex::Graph graph(num_faces);
    tex::build_adjacency_graph(mesh, mesh_info, &graph);

    if (conf.labeling_file.empty()) {
        std::cout << "View selection:" << std::endl;
        util::WallTimer rwtimer;

        tex::DataCosts data_costs(num_faces, texture_views.size());
        if (conf.data_cost_file.empty()) {
            tex::calculate_data_costs(mesh, &texture_views, conf.settings, &data_costs);

            if (conf.write_intermediate_results) {
                std::cout << "\tWriting data cost file... " << std::flush;
                    ST::save_to_file(data_costs, conf.out_prefix + "_data_costs.spt");
                std::cout << "done." << std::endl;
            }
        } else {
            std::cout << "\tLoading data cost file... " << std::flush;
            try {
                ST::load_from_file(conf.data_cost_file, &data_costs);
            } catch (util::FileException e) {
                std::cout << "failed!" << std::endl;
                std::cerr << e.what() << std::endl;
                std::exit(EXIT_FAILURE);
            }
            std::cout << "done." << std::endl;
        }
        timer.measure("Calculating data costs");

        tex::view_selection(data_costs, &graph, conf.settings);
        timer.measure("Running MRF optimization");
        std::cout << "\tTook: " << rwtimer.get_elapsed_sec() << "s" << std::endl;

        /* Write labeling to file. */
        if (conf.write_intermediate_results) {
            std::vector<std::size_t> labeling(graph.num_nodes());
            for (std::size_t i = 0; i < graph.num_nodes(); ++i) {
                labeling[i] = graph.get_label(i);
            }
            vector_to_file(conf.out_prefix + "_labeling.vec", labeling);
        }
    } else {
        std::cout << "Loading labeling from file... " << std::flush;

        /* Load labeling from file. */
        std::vector<std::size_t> labeling = vector_from_file<std::size_t>(conf.labeling_file);
        if (labeling.size() != graph.num_nodes()) {
            std::cerr << "Wrong labeling file for this mesh/scene combination... aborting!" << std::endl;
            std::exit(EXIT_FAILURE);
        }

        /* Transfer labeling to graph. */
        for (std::size_t i = 0; i < labeling.size(); ++i) {
            const std::size_t label = labeling[i];
            if (label > texture_views.size()){
                std::cerr << "Wrong labeling file for this mesh/scene combination... aborting!" << std::endl;
                std::exit(EXIT_FAILURE);
            }
            graph.set_label(i, label);
        }

        std::cout << "done." << std::endl;
    }

    tex::TextureAtlases texture_atlases;
    {
        /* Create texture patches and adjust them. */
        tex::TexturePatches texture_patches;
        tex::VertexProjectionInfos vertex_projection_infos;
        std::cout << "Generating texture patches:" << std::endl;
        tex::generate_texture_patches(graph, mesh, mesh_info, &texture_views, &vertex_projection_infos, &texture_patches);

        if (conf.settings.global_seam_leveling) {
            std::cout << "Running global seam leveling:" << std::endl;
            tex::global_seam_leveling(graph, mesh, mesh_info, vertex_projection_infos, &texture_patches);
            timer.measure("Running global seam leveling");
        } else {
            ProgressCounter texture_patch_counter("Calculating validity masks for texture patches", texture_patches.size());
            #pragma omp parallel for schedule(dynamic)
            for (std::size_t i = 0; i < texture_patches.size(); ++i) {
                texture_patch_counter.progress<SIMPLE>();
                TexturePatch::Ptr texture_patch = texture_patches[i];
                std::vector<math::Vec3f> patch_adjust_values(texture_patch->get_faces().size() * 3, math::Vec3f(0.0f));
                texture_patch->adjust_colors(patch_adjust_values);
                texture_patch_counter.inc();
            }
            timer.measure("Calculating texture patch validity masks");
        }

        if (conf.settings.local_seam_leveling) {
            std::cout << "Running local seam leveling:" << std::endl;
            tex::local_seam_leveling(graph, mesh, vertex_projection_infos, &texture_patches);
        }
        timer.measure("Running local seam leveling");

        /* Generate texture atlases. */
        std::cout << "Generating texture atlases:" << std::endl;
        tex::generate_texture_atlases(&texture_patches, &texture_atlases);
    }

    /* Create and write out obj model. */
    {
        std::cout << "Building objmodel:" << std::endl;
        tex::Model model;
        tex::build_model(mesh, texture_atlases, &model);
        timer.measure("Building OBJ model");

        std::cout << "\tSaving model... " << std::flush;
        tex::Model::save(model, conf.out_prefix);
        std::cout << "done." << std::endl;
        timer.measure("Saving");
    }

    std::cout << "Whole texturing procedure took: " << wtimer.get_elapsed_sec() << "s" << std::endl;
    timer.measure("Total");
    if (conf.write_timings) {
        timer.write_to_file(conf.out_prefix + "_timings.csv");
    }

    if (conf.write_view_selection_model) {
        texture_atlases.clear();
        std::cout << "Generating debug texture patches:" << std::endl;
        {
            tex::TexturePatches texture_patches;
            generate_debug_embeddings(&texture_views);
            tex::VertexProjectionInfos vertex_projection_infos; // Will only be written
            tex::generate_texture_patches(graph, mesh, mesh_info, &texture_views, &vertex_projection_infos, &texture_patches);
            tex::generate_texture_atlases(&texture_patches, &texture_atlases);
        }

        std::cout << "Building debug objmodel:" << std::endl;
        {
            tex::Model model;
            tex::build_model(mesh, texture_atlases, &model);
            std::cout << "\tSaving model... " << std::flush;
            tex::Model::save(model, conf.out_prefix + "_view_selection");
            std::cout << "done." << std::endl;
        }
    }

    return EXIT_SUCCESS;
}
예제 #2
0
void
do_pgr_tsp(
        Matrix_cell_t *distances,
        size_t total_distances,
        int64_t start_vid,
        int64_t end_vid,

        double initial_temperature,
        double final_temperature,
        double cooling_factor,
        int64_t tries_per_temperature,
        int64_t max_changes_per_temperature,
        int64_t max_consecutive_non_changes,
        bool randomize,
        double time_limit,

        General_path_element_t **return_tuples,
        size_t *return_count,
        char **log_msg,
        char **err_msg) {
    std::ostringstream err;
    std::ostringstream log;

    try {
        std::vector < Matrix_cell_t > data_costs(
                distances,
                distances + total_distances);

        pgrouting::tsp::Dmatrix costs(data_costs);

        if (!costs.has_no_infinity()) {
            err << "An Infinity value was found on the Matrix";
            *err_msg = strdup(err.str().c_str());
            *log_msg = strdup(log.str().c_str());
            return;
        }

        if (!costs.is_symmetric()) {
            err << "A Non symmetric Matrix was given as input";
            *err_msg = strdup(err.str().c_str());
            *log_msg = strdup(log.str().c_str());
            return;
        }

        double real_cost = -1;

        size_t idx_start = costs.has_id(start_vid) ?
            costs.get_index(start_vid) : 0;

        size_t idx_end = costs.has_id(end_vid) ?
            costs.get_index(end_vid) : 0;

        if (costs.has_id(start_vid) && costs.has_id(end_vid) && start_vid != end_vid) {
            /* An ending vertex needs to be by the starting vertex */
            real_cost = costs.distance(idx_start, idx_end);
            costs.set(idx_start, idx_end, 0);
        }


        log << "pgr_eucledianTSP Processing Information \nInitializing tsp class --->";
        pgrouting::tsp::TSP<pgrouting::tsp::Dmatrix> tsp(costs);


        log << " tsp.greedyInitial --->";
        tsp.greedyInitial(idx_start);



        log << " tsp.annealing --->";
        tsp.annealing(
                initial_temperature,
                final_temperature,
                cooling_factor,
                tries_per_temperature,
                max_changes_per_temperature,
                max_consecutive_non_changes,
                randomize,
                time_limit);
        log << " OK\n";
        log << tsp.get_log();
        log << tsp.get_stats();

        auto bestTour(tsp.get_tour());

        if (costs.has_id(start_vid) && costs.has_id(end_vid) && start_vid != end_vid) {
            costs.set(idx_start, idx_end, real_cost);
        }


        log << "\nBest cost reached = " << costs.tourCost(bestTour);

        auto start_ptr = std::find(
                bestTour.cities.begin(),
                bestTour.cities.end(),
                idx_start);


        std::rotate(
                bestTour.cities.begin(),
                start_ptr,
                bestTour.cities.end());

        if (costs.has_id(start_vid) && costs.has_id(end_vid) && start_vid != end_vid) {
            if (*(bestTour.cities.begin() + 1) == idx_end) {
                std::reverse(
                        bestTour.cities.begin() + 1,
                        bestTour.cities.end());
            }
        }


        std::vector< General_path_element_t > result;
        result.reserve(bestTour.cities.size() + 1);
        pgassert(bestTour.cities.size() == costs.size());

        bestTour.cities.push_back(bestTour.cities.front());

        auto prev_id = bestTour.cities.front();
        double agg_cost = 0;
        for (const auto &id : bestTour.cities) {
            if (id == prev_id) continue;
            General_path_element_t data;
            data.node = costs.get_id(prev_id);
            data.edge = prev_id;
            data.cost = costs.distance(prev_id, id);
            data.agg_cost = agg_cost;
            result.push_back(data);
            agg_cost += data.cost;
            prev_id = id;
        }

        /* inserting the returning to starting point */
        {
            General_path_element_t data;
            data.node = costs.get_id(bestTour.cities.front());
            data.edge = bestTour.cities.front();
            data.cost = costs.distance(prev_id, bestTour.cities.front());
            agg_cost += data.cost;
            data.agg_cost = agg_cost;
            result.push_back(data);
        }

        pgassert(result.size() == bestTour.cities.size());
        *return_count = bestTour.size();
        (*return_tuples) = pgr_alloc(result.size(), (*return_tuples));

        /* store the results */
        int seq = 0;
        for (const auto &row : result) {
            (*return_tuples)[seq] = row;
            ++seq;
        }

        *log_msg = strdup(log.str().c_str());
        (*err_msg) = NULL;
        return;
    } catch (AssertFailedException &except) {
        if (*return_tuples) free(*return_tuples);
        (*return_count) = 0;
        err << except.what() << "\n";
        *err_msg = strdup(err.str().c_str());
        *log_msg = strdup(log.str().c_str());
    } catch (std::exception& except) {
        if (*return_tuples) free(*return_tuples);
        (*return_count) = 0;
        err << except.what() << "\n";
        *err_msg = strdup(err.str().c_str());
        *log_msg = strdup(log.str().c_str());
    } catch(...) {
        if (*return_tuples) free(*return_tuples);
        (*return_count) = 0;
        err << "Caught unknown exception!\n";
        *err_msg = strdup(err.str().c_str());
        *log_msg = strdup(log.str().c_str());
    }
}