Example #1
0
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);
}