#include "debug.h" #include #include #include #include #include #include #include #include #include // IO #include #include namespace po = boost::program_options; using namespace CGAL::parameters; // Domain // (we use exact intersection computation with Robust_intersection_traits_3) struct K: public CGAL::Exact_predicates_inexact_constructions_kernel {}; typedef CGAL::Mesh_3::Robust_intersection_traits_3 Geom_traits; typedef CGAL::Polyhedron_3 Polyhedron; typedef CGAL::Polyhedral_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(); } } 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 polyhedron contained in that file"); 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") ("off_vertices", "Use polyhedron vertices as initialization step") ("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"); 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 polyhedron_filename = set_arg("file", "Filename", vm); std::cout << "=============================="<< std::endl; std::cout << std::endl; if ( polyhedron_filename.empty() ) { std::cout << "No file selected. Exit.\n"; return 0; } // Loads polyhedron Polyhedron polyhedron; std::ifstream input(polyhedron_filename.c_str()); input >> polyhedron; using std::atof; // Domain Mesh_domain domain(polyhedron); // 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); // Mesh generation C3t3 c3t3; if ( !vm.count("off_vertices") ) { c3t3 = CGAL::make_mesh_3(domain, criteria, no_exude(), no_perturb()); } else { c3t3.insert_surface_points(polyhedron.points_begin(), polyhedron.points_end(), domain.make_surface_index()); CGAL::refine_mesh_3(c3t3, domain, criteria, no_exude(), no_perturb()); } // Output std::ofstream medit_file_before("out_before.mesh"); c3t3.output_to_medit(medit_file_before, vm.count("no_label_rebind") == 0, vm.count("show_patches") > 0); // 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") == 0, vm.count("show_patches") > 0); return 0; }