int main(int argc, char **argv) { if(argc < 2) { std::cout << "usage: mesh_file_name [first_vertex] [second_vertex]" << std::endl; //try: "hedgehog_mesh.txt 3 14" or "flat_triangular_mesh.txt 1" return 0; } std::vector<double> points; std::vector<unsigned> faces; bool success = geodesic::read_mesh_from_file(argv[1],points,faces); if(!success) { std::cout << "something is wrong with the input file" << std::endl; return 0; } geodesic::Mesh mesh; mesh.initialize_mesh_data(points, faces); //create internal mesh data structure including edges geodesic::GeodesicAlgorithmExact algorithm(&mesh); //create exact algorithm for the mesh unsigned source_vertex_index = (argc == 2) ? 0 : atol(argv[2]); geodesic::SurfacePoint source(&mesh.vertices()[source_vertex_index]); //create source std::vector<geodesic::SurfacePoint> all_sources(1,source); //in general, there could be multiple sources, but now we have only one if(argc > 3) //target vertex specified, compute single path { unsigned target_vertex_index = atol(argv[3]); geodesic::SurfacePoint target(&mesh.vertices()[target_vertex_index]); //create source std::vector<geodesic::SurfacePoint> path; //geodesic path is a sequence of SurfacePoints double const distance_limit = geodesic::GEODESIC_INF; // no limit for propagation std::vector<geodesic::SurfacePoint> stop_points(1, target); //stop propagation when the target is covered algorithm.propagate(all_sources, distance_limit, &stop_points); //"propagate(all_sources)" is also fine, but take more time because covers the whole mesh algorithm.trace_back(target, path); //trace back a single path print_info_about_path(path); } return 0; }
bool GeodesicProvider::computation() { if (!this->m_model) { _GT_LOGGER_ERR(this->name(), "Subroutine <computation> failed. Missing model."); return (false); } const openmesh::Mesh &mesh(this->m_model->mesh()); // Verifies settings and prepares geodesic algorithm. _GT_LOGGER_MSG(this->name(), "Verifying settings and preparing geodesic algorithm."); std::vector<size_t> source_indices = this->m_source_vertices.data(); std::vector<size_t> target_indices = this->m_target_vertices.data(); if (source_indices.empty()) { source_indices.resize(mesh.n_vertices()); for (size_t i = 0; i < mesh.n_vertices(); ++i) source_indices[i] = i; } if (target_indices.empty()) { target_indices.resize(mesh.n_vertices()); for (size_t i = 0; i < mesh.n_vertices(); ++i) target_indices[i] = i; } if (((int64_t)sizeof(real_t) * source_indices.size() * target_indices.size()) > (int64_t)GT_INT32_MAX) { _GT_LOGGER_ERR(this->name(), "Subroutine <computation> failed. Storage of data demanded exceeds size of memory."); return (false); } std::vector<real_t> vertices(mesh.n_vertices() * 3); std::vector<size_t> faces(mesh.n_faces() * 3); for (openmesh::Mesh::ConstVertexIter cv_iter = mesh.vertices_begin(); cv_iter != mesh.vertices_end(); ++cv_iter) { size_t offset = cv_iter.handle().idx() * 3; const openmesh::Mesh::Point &point(mesh.point(cv_iter.handle())); vertices[offset + 0] = point[0]; vertices[offset + 1] = point[1]; vertices[offset + 2] = point[2]; } for (openmesh::Mesh::ConstFaceIter cf_iter = mesh.faces_begin(); cf_iter != mesh.faces_end(); ++cf_iter) { size_t offset = cf_iter.handle().idx() * 3; openmesh::Mesh::ConstFaceVertexIter cfv_iter = mesh.cfv_iter(cf_iter.handle()); faces[offset + 0] = ( cfv_iter).handle().idx(); faces[offset + 1] = (++cfv_iter).handle().idx(); faces[offset + 2] = (++cfv_iter).handle().idx(); } geodesic::Mesh geode_mesh; geode_mesh.initialize_mesh_data(vertices, faces); geodesic::GeodesicAlgorithmBase *algorithm = NULL; switch (this->m_algorithm_option.data()) { case 0: // 'Algorithm': Dijkstra. algorithm = new geodesic::GeodesicAlgorithmDijkstra(&geode_mesh); break; case 1: // 'Algorithm': Exact. algorithm = new geodesic::GeodesicAlgorithmExact(&geode_mesh); break; case 2: // 'Algorithm': Subdivision. algorithm = new geodesic::GeodesicAlgorithmSubdivision(&geode_mesh, this->m_subdivision_level.data()); break; } if (!algorithm) { _GT_LOGGER_ERR(this->name(), "Subroutine <computation> failed. No suitable algorithm found."); return (false); } // Computes geodesic distances. _GT_LOGGER_MSG(this->name(), "Computing geodesic distances."); std::vector<geodesic::SurfacePoint> targets(target_indices.size()); for (size_t i = 0; i < target_indices.size(); ++i) { targets[i] = geodesic::SurfacePoint(&geode_mesh.vertices()[target_indices[i]]); } this->m_geodesics.resize(source_indices.size(), target_indices.size()); _GT_LOGGER_BEG_PROG; for (size_t i = 0; i < source_indices.size(); ++i) { _GT_LOGGER_UPD_PROG(i, source_indices.size()); std::vector<geodesic::SurfacePoint> sources(1, geodesic::SurfacePoint(&geode_mesh.vertices()[source_indices[i]])); std::vector<geodesic::SurfacePoint> stop_points(targets); algorithm->propagate(sources, geodesic::GEODESIC_INF, &stop_points); for (size_t j = 0; j < target_indices.size(); ++j) { real_t distance; algorithm->best_source(targets[j], distance); this->m_geodesics(i, j) = distance; } } _GT_LOGGER_END_PROG; delete algorithm; return (true); }