#include // regular #include #include #include // IO.h must be included before vertex and cell bases. #include // vertex and cell bases #include #include #include // c2t3 #include // traits class for reading meshes #include // radius_ratio #include // Point_traits #include #include // traits class typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Regular_triangulation_filtered_traits_3 Regular_traits; typedef CGAL::Weighted_point_with_surface_index_geom_traits My_traits; // vertex and cell types typedef CGAL::Surface_mesh_vertex_base_3 Vb; typedef CGAL::Regular_triangulation_cell_base_3 Cb1; typedef CGAL::Surface_mesh_cell_base_3 Cb2; typedef CGAL::Volume_mesher_cell_base_3 Cb3; template > class Cell_with_volume_index : public Cb { private: int volume; public: typedef typename GT::Point_3 Point; typedef typename Cb::Triangulation_data_structure Tds; typedef typename Tds::Vertex_handle Vertex_handle; typedef typename Tds::Cell_handle Cell_handle; template < class TDS3 > struct Rebind_TDS { typedef typename Cb::template Rebind_TDS::Other Cb3; typedef Cell_with_volume_index Other; }; // Constructors Cell_with_volume_index() : Cb(), volume(0) { } Cell_with_volume_index (Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) : Cb (v0, v1, v2, v3), volume(0) { } Cell_with_volume_index (Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, Cell_handle n0, Cell_handle n1, Cell_handle n2, Cell_handle n3) : Cb (v0, v1, v2, v3, n0, n1, n2, n3), volume(0) { } // volume index int volume_index() const { return volume; } void set_volume_index(const int i) { volume = i; } #ifdef CGAL_MESH_3_IO_H static std::string io_signature() { return CGAL::Get_io_signature()(); } #endif }; // end template class Cell_with_volume_index template inline std::istream& operator>>(std::istream &is, Cell_with_volume_index& c) { return is >> static_cast(c); } template inline std::ostream& operator<<(std::ostream &os, const Cell_with_volume_index& c) { return os << static_cast(c); } typedef Cell_with_volume_index Cb; // triangulation typedef CGAL::Triangulation_data_structure_3 Tds; typedef CGAL::Regular_triangulation_3 Tr; // c2t3 typedef CGAL::Complex_2_in_triangulation_3 C2T3; // ios #include #include #include #include #include #include int main(int , char**) { Tr tr; C2T3 c2t3(tr); double r1, r2, r3, r4, r5; std::vector size_bounds(5); std::vector radii(5); std::cout << "Input r1, r2, r3, r4, r5:" << std::endl; std::cin >> r1 >> r2 >> r3 >> r4 >> r5; std::cout << "Input the corresponding 5 size bounds:" << std::endl; std::cin >> size_bounds[0] >> size_bounds[1] >> size_bounds[2] >> size_bounds[3] >> size_bounds[4]; if(!std::cin) return EXIT_FAILURE; std::string file_prefix; std::cout << "Input filename prefix:" << std::endl; std::cin >> file_prefix; // input file std::ifstream ifs((file_prefix + ".cgal").c_str()); // ouput tets mesh file std::ofstream ofs_maillage((file_prefix + ".maillage").c_str()); // output five surface meshes files std::vector ofs_surfaces(6); // ofs_surfaces[0] will not be used. for(int i = 1; i <= 5; ++i) { std::stringstream str_stream; str_stream << file_prefix << ".surface" << i; ofs_surfaces[i] = new std::ofstream(str_stream.str().c_str()); } std::cout << " Reading file " << (file_prefix + ".cgal") << std::endl; if( CGAL::Mesh_3::input_mesh(ifs, c2t3, true, &std::cerr) ) { std::cout << " Writing file " << (file_prefix + ".maillage") << std::endl << " and files " << (file_prefix + ".surface*") << std::endl; typedef C2T3::Triangulation Tr; typedef Tr::Finite_cells_iterator Finite_cells_iterator; typedef Tr::Finite_facets_iterator Finite_facets_iterator; typedef Tr::Finite_vertices_iterator Finite_vertices_iterator; typedef Tr::Vertex_handle Vertex_handle; typedef Tr::Point Point; typedef CGAL::Point_traits P_traits; typedef P_traits::Bare_point Bare_point; // sets volume indices for(Tr::Finite_cells_iterator cit = tr.finite_cells_begin(); cit != tr.finite_cells_end(); ++cit) if(cit->is_in_domain()) { const double sq_r = squared_distance(K::Point_3(0, 0, 0), static_cast(tr.dual(cit))); if( sq_r < r1*r1 ) cit->set_volume_index(1); // brain else if( sq_r < r2*r2 ) cit->set_volume_index(2); // LCR else if( sq_r < r3*r3 ) cit->set_volume_index(3); // head skull else if( sq_r < r4*r4 ) cit->set_volume_index(4); // skin else if( sq_r < r5*r5 ) cit->set_volume_index(-1);// air } const Tr& tr = c2t3.triangulation(); // Headers ofs_maillage << tr.number_of_vertices() << " " << CGAL::number_of_cells_in_domain(tr) << " " << CGAL::number_of_facets_on_surface_with_index(c2t3, 5) << std::endl; for(int i = 1; i <= 5; ++i) { *ofs_surfaces[i] << tr.number_of_vertices() << " " << CGAL::number_of_facets_on_surface_with_index(c2t3, i) << std::endl; } // precision ofs_maillage << std::setprecision(20); for(int i = 1; i <= 5; ++i) { *ofs_surfaces[i] << std::setprecision(20); } // Vertices std::map V; // vertices are counter from 1 int inum = 1; for( Finite_vertices_iterator vit = tr.finite_vertices_begin(); vit != tr.finite_vertices_end(); ++vit) { V[vit] = inum++; Point p = static_cast(vit->point()); ofs_maillage << p.x() << " " << p.y() << " " << p.z() << std::endl; for(int i = 1; i <= 5; ++i) { *ofs_surfaces[i] << p.x() << " " << p.y() << " " << p.z() << std::endl; } } // Tetrahedra for( Finite_cells_iterator cit = tr.finite_cells_begin(); cit != tr.finite_cells_end(); ++cit) if( cit->is_in_domain() ) { for (int i=0; i<4; i++) ofs_maillage << V[cit->vertex(i)] << " "; ofs_maillage << cit->volume_index() << std::endl; } // Facets for( Finite_facets_iterator fit = tr.finite_facets_begin(); fit != tr.finite_facets_end(); ++fit) { int surface_index = 0; if (c2t3.face_status(fit->first,fit->second) != C2T3::NOT_IN_COMPLEX) { for (int i=0; i<4; i++) if (i != (*fit).second) { const Vertex_handle& vh = (*fit).first->vertex(i); surface_index = vh->point().surface_index(); if(surface_index == 5) { ofs_maillage << V[vh] << " "; } *ofs_surfaces[surface_index] << V[vh] << " "; } if(surface_index == 5) ofs_maillage << "4" << std::endl; *ofs_surfaces[surface_index] << surface_index << std::endl; } } for(int i = 1; i <= 5; ++i) if( ofs_surfaces[i]->bad() ) return EXIT_FAILURE; if( ofs_maillage.good() ) { for(int i = 1; i <= 5; ++i) delete ofs_surfaces[i]; return EXIT_SUCCESS; } else return EXIT_FAILURE; } else return EXIT_FAILURE; }