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