Goosefoot Mesher - CGAL
write_c3t3_to_gmsh_file.h
1 
41 // ACKNOWLEDGEMENT: This approach was inspired by David Bernstein's post to cgal-discuss
42 
43 #ifndef Mesh_3_example_write_c3t3_to_gmsh_file_h
44 #define Mesh_3_example_write_c3t3_to_gmsh_file_h
45 
46 #include "mesher_cgal.h"
47 
48 #include <map>
49 
50 namespace CGAL {
51  template<class C3t3, class Polyhedron>
52  bool write_c3t3_to_gmsh_file(const C3t3 &c3t3, std::map<typename C3t3::Triangulation::Facet,int>& boundary_indices, const std::string &file_name, bool decrement_zone=false, bool number_from_zero=false)
53  {
54  typedef typename C3t3::Triangulation Tr;
55  typedef typename C3t3::Cells_in_complex_iterator Cell_iterator;
56  typedef typename C3t3::Facets_in_complex_iterator Facet_iterator;
57  typedef typename Tr::Finite_vertices_iterator Vertex_iterator;
58 
59  // Domain
60  typedef Exact_predicates_inexact_constructions_kernel K;
61  typedef K::Point_3 Point;
62 
63  // check that file extension is "msh"
64  CGAL_assertion(file_name.substr(file_name.length()-4,4) == ".msh");
65 
66  // open file
67  std::ofstream gmsh_file(file_name.c_str());
68 
69  // header
70  gmsh_file << "$MeshFormat" << std::endl << "2.0 0 8" << std::endl << "$EndMeshFormat" << std::endl;
71 
72  // write mesh
73  Tr t = c3t3.triangulation();
74  int num_vertices = t.number_of_vertices();
75  int num_facets = c3t3.number_of_facets_in_complex();
76  int num_cells = c3t3.number_of_cells_in_complex();
77  std::cout << num_facets << " - " << num_cells << std::endl;
78 
79  Cell_iterator it;
80 
81  // Write vertices
82  std::map<Point, int> V;
83  int i=0, j=0;
84  int i_delta = number_from_zero ? 0 : 1;
85  for (it = c3t3.cells_in_complex_begin(); it != c3t3.cells_in_complex_end(); ++it)
86  for (j = 0 ; j < 4 ; j++)
87  if (V.count(it->vertex(j)->point()) == 0) {
88  i++;
89  V[it->vertex(j)->point()] = -1;
90  }
91 
92  num_vertices = i;
93  gmsh_file << "$Nodes" << std::endl;
94  gmsh_file << num_vertices << std::endl;
95 
96  i = 0;
97  for (Vertex_iterator it=t.finite_vertices_begin(); it != t.finite_vertices_end(); ++it)
98  {
99  if (V.count(it->point()) == 0) {
100  std::cout << " (removed redundant vertex: " << i << ")" << std::endl;
101  continue;
102  }
103  gmsh_file << i + i_delta << " " << it->point().x() << " " << it->point().y() << " " << it->point().z() << std::endl;
104  V[it->point()] = i;
105  ++i;
106  }
107 
108  gmsh_file << "$EndNodes" << std::endl;
109 
110  // Write tetrahedra
111  gmsh_file << "$Elements" << std::endl;
112 
113  gmsh_file << num_cells + num_facets;
114  gmsh_file << std::endl;
115 
116  std::vector<int> indices(3, 0);
117 
118  int elt = number_from_zero ? -1 : 0;
119  Facet_iterator fit;
120  for (fit = c3t3.facets_in_complex_begin(); fit != c3t3.facets_in_complex_end(); ++fit)
121  {
122  elt++;
123  int j=-1;
124 
125  for (int i = 0; i < 4; ++i)
126  if (i != fit->second)
127  indices[++j] = V[(*fit).first->vertex(i)->point()];
128  //if ( fit->second%2 == 1 ) std::swap(indices[0],indices[1]); RMV
129  int subId = boundary_indices[(*fit)];
130  std::sort(indices.begin(), indices.end());
131  gmsh_file << elt << " 2 2 " << subId << " " << subId << " " << indices[0] + i_delta <<" " << indices[1] + i_delta <<" " << indices[2] + i_delta << std::endl;
132  }
133 
134  for (it = c3t3.cells_in_complex_begin(); it != c3t3.cells_in_complex_end(); ++it)
135  {
136  int subId = c3t3.subdomain_index(it);
137  if (decrement_zone)
138  subId--;
139  gmsh_file << ++elt << " 4 2 " << subId << " " << subId << " ";
140  gmsh_file << V[it->vertex(0)->point()] + i_delta << " ";
141  gmsh_file << V[it->vertex(1)->point()] + i_delta << " ";
142  gmsh_file << V[it->vertex(2)->point()] + i_delta << " ";
143  gmsh_file << V[it->vertex(3)->point()] + i_delta << std::endl;
144  }
145 
146  gmsh_file << "$EndElements" << std::endl;
147 
148  return true;
149  }
150 } // end namespace CGAL
151 
152 #endif
Definition: write_c3t3_to_gmsh_file.h:50