#include "debug.h" #include #include #include #include #include #include #include #include #include namespace po = boost::program_options; // Domain struct K: public CGAL::Exact_predicates_inexact_constructions_kernel {}; typedef CGAL::Image_3 Image; typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Mesh Criteria typedef CGAL::Mesh_criteria_3 Mesh_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; template T set_arg(const std::string& param_name, const std::string& param_string, const po::variables_map& vm) { if ( vm.count(param_name) ) { T param_value = vm[param_name].as(); std::cout << param_string << ": " << param_value << "\n"; return param_value; } else { std::cout << param_string << " ignored.\n"; return T(); } } // To avoid verbose function and named parameters call using namespace CGAL::parameters; int main(int argc, char** argv) { po::options_description generic("Generic options"); generic.add_options() ("help", "Produce help message"); generic.add_options()("file", po::value(), "Mesh image contained in that file"); generic.add_options()("raw", po::value(), "Image is in raw format. Parameters are given by arg file [rx, ry, rz, vx, vy, vz], one per line"); po::options_description mesh("Mesh generation parameters"); mesh.add_options()("facet_angle", po::value(), "Set facet angle bound") ("facet_size", po::value(), "Set facet size bound") ("facet_error", po::value(), "Set facet approximation error bound") ("tet_shape", po::value(), "Set tet radius-edge bound") ("tet_size", po::value(), "Set tet size bound"); po::options_description desc("Options"); desc.add_options() ("exude", po::value(), "Exude mesh after refinement. arg is time_limit.") ("perturb", po::value(), "Perturb (sliver removal) mesh after refinement. arg is time_limit") ("lloyd", po::value(), "Lloyd-smoothing after refinement. arg is max_iteration_nb") ("odt", po::value(), "ODT-smoothing after refinement. arg is max_iteration_nb") ("convergence", po::value()->default_value(0.02), "Convergence ratio for smoothing functions") ("min_displacement", po::value()->default_value(0.01), "Minimal displacement ratio for smoothing functions (moves that are below that ratio will not be done)") ("time_limit", po::value()->default_value(0), "Max time for smoothing functions") ("no_label_rebind", "Don't rebind cell labels in medit output") ("show_patches", "Show surface patches in medit output"); po::options_description cmdline_options("Usage",1); cmdline_options.add(generic).add(mesh).add(desc); po::variables_map vm; po::store(po::parse_command_line(argc, argv, cmdline_options), vm); po::notify(vm); if (vm.count("help") || argc < 2) { std::cout << cmdline_options << std::endl; return 1; } std::cout << "=========== Params ==========="<< std::endl; double facet_angle = set_arg("facet_angle","Facet angle",vm); double facet_size = set_arg("facet_size","Facet size",vm); double facet_error = set_arg("facet_error","Facet approximation error",vm); double tet_shape = set_arg("tet_shape","Tet shape (radius-edge)",vm); double tet_size = set_arg("tet_size","Tet size",vm); std::cout << std::endl; std::string image_filename = set_arg("file", "Filename", vm); std::string raw_file_params; if ( vm.count("raw") ) raw_file_params = set_arg("raw", "Raw parameters file", vm); std::cout << "=============================="<< std::endl; std::cout << std::endl; if ( image_filename.empty() ) { std::cout << "No file selected. Exit.\n"; return 0; } // Loads image Image image; if ( ! vm.count("raw") ) { image.read(image_filename.c_str()); } else { int rx = 0; int ry = 0; int rz = 0; double vx = 0.; double vy = 0.; double vz = 0.; std::ifstream raw_file(raw_file_params.c_str()); raw_file >> rx >> ry >> rz; raw_file >> vx >> vy >> vz; image.read_raw(image_filename.c_str(),rx,ry,rz,vx,vy,vz); } // Domain Mesh_domain domain(image, 1e-9); // Mesh criteria Facet_criteria facet_criteria(facet_angle, facet_size, facet_error); // angle, size, approximation Cell_criteria cell_criteria(tet_shape, tet_size); // radius-edge ratio, size Mesh_criteria criteria(facet_criteria, cell_criteria); // Meshing C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, no_exude(), no_perturb()); // Odt if ( vm.count("odt") ) { CGAL::odt_optimize_mesh_3(c3t3, domain, max_iteration_number=vm["odt"].as(), convergence=vm["convergence"].as(), sliver_bound=vm["min_displacement"].as(), time_limit=vm["time_limit"].as()); } // Lloyd if ( vm.count("lloyd") ) { CGAL::lloyd_optimize_mesh_3(c3t3, domain, max_iteration_number=vm["lloyd"].as(), convergence=vm["convergence"].as(), sliver_bound=vm["min_displacement"].as(), time_limit=vm["time_limit"].as()); } // Perturbation if ( vm.count("perturb") ) { CGAL::perturb_mesh_3(c3t3, domain, time_limit = vm["perturb"].as() ); } // Exudation if ( vm.count("exude") ) { CGAL::exude_mesh_3(c3t3, time_limit = vm["exude"].as()); } double min_angle = 181.; for ( C3t3::Cell_iterator cit = c3t3.cells_begin() ; cit != c3t3.cells_end() ; ++cit ) { min_angle = (std::min)(min_angle, CGAL::to_double(CGAL::Mesh_3::minimum_dihedral_angle(c3t3.triangulation().tetrahedron(cit)))); } std::cerr << "Min angle: " << min_angle << std::endl; // Output std::ofstream medit_file("out.mesh"); c3t3.output_to_medit(medit_file,!vm.count("no_label_rebind"), vm.count("show_patches")); return 0; }