RINGMesh  Version 5.0.0
A programming library for geological model meshes
io_vtk.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2017, Association Scientifique pour la Geologie et ses
3  * Applications (ASGA). All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of ASGA nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ASGA BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * http://www.ring-team.org
28  *
29  * RING Project
30  * Ecole Nationale Superieure de Geologie - GeoRessources
31  * 2 Rue du Doyen Marcel Roubault - TSA 70605
32  * 54518 VANDOEUVRE-LES-NANCY
33  * FRANCE
34  */
35 
36 namespace {
37  struct RINGMesh2VTK {
38  index_t entity_type;
39  index_t vertices[8];
40  };
41 
42  static RINGMesh2VTK tet_descriptor_vtk = { 10, // type
43  { 0, 1, 2, 3 } // vertices
44  };
45 
46  static RINGMesh2VTK hex_descriptor_vtk = { 12, // type
47  { 0, 4, 5, 1, 2, 6, 7, 3 } // vertices
48  };
49 
50  static RINGMesh2VTK prism_descriptor_vtk = { 13, // type
51  { 0, 2, 1, 3, 5, 4 } // vertices
52  };
53 
54  static RINGMesh2VTK pyramid_descriptor_vtk = { 14, // type
55  { 0, 1, 2, 3, 4 } // vertices
56  };
57 
58  static RINGMesh2VTK* cell_type_to_cell_descriptor_vtk[4] = {
59  &tet_descriptor_vtk, &hex_descriptor_vtk, &prism_descriptor_vtk,
60  &pyramid_descriptor_vtk };
61 
62  class VTKIOHandler final: public GeoModelIOHandler< 3 > {
63  public:
64  void load( const std::string& filename, GeoModel3D& geomodel ) final
65  {
66  ringmesh_unused( filename );
67  ringmesh_unused( geomodel );
68  throw RINGMeshException( "I/O",
69  "Loading of a GeoModel from VTK not implemented yet" );
70  }
71  void save(
72  const GeoModel3D& geomodel,
73  const std::string& filename ) final
74  {
75  std::ofstream out( filename.c_str() );
76  out.precision( 16 );
77 
78  out << "# vtk DataFile Version 2.0" << EOL;
79  out << "Unstructured Grid" << EOL;
80  out << "ASCII" << EOL;
81  out << "DATASET UNSTRUCTURED_GRID" << EOL;
82 
83  const auto& mesh = geomodel.mesh;
84  out << "POINTS " << mesh.vertices.nb() << " double" << EOL;
85  for( auto v : range( mesh.vertices.nb() ) ) {
86  out << mesh.vertices.vertex( v ) << EOL;
87  }
88  out << EOL;
89 
90  index_t total_corners = ( 4 + 1 ) * mesh.cells.nb_tet()
91  + ( 5 + 1 ) * mesh.cells.nb_pyramid()
92  + ( 6 + 1 ) * mesh.cells.nb_prism()
93  + ( 8 + 1 ) * mesh.cells.nb_hex();
94  out << "CELLS " << mesh.cells.nb_cells() << SPACE << total_corners
95  << EOL;
96  for( auto c : range( mesh.cells.nb() ) ) {
97  out << mesh.cells.nb_vertices( c );
98  const auto& descriptor =
99  *cell_type_to_cell_descriptor_vtk[to_underlying_type( mesh.cells.type( c ) )];
100  for( auto v : range( mesh.cells.nb_vertices( c ) ) ) {
101  auto vertex_id = descriptor.vertices[v];
102  out << SPACE
103  << mesh.cells.vertex( { c, vertex_id } );
104  }
105  out << EOL;
106  }
107 
108  out << "CELL_TYPES " << mesh.cells.nb() << EOL;
109  for( auto c : range( mesh.cells.nb() ) ) {
110  const auto& descriptor =
111  *cell_type_to_cell_descriptor_vtk[to_underlying_type( mesh.cells.type( c ) )];
112  out << descriptor.entity_type << EOL;
113  }
114  out << EOL;
115 
116  out << "CELL_DATA " << mesh.cells.nb() << EOL;
117  out << "SCALARS region int 1" << EOL;
118  out << "LOOKUP_TABLE default" << EOL;
119  for( auto c : range( mesh.cells.nb() ) ) {
120  out << mesh.cells.region( c ) << EOL;
121  }
122  out << EOL;
123  out << std::flush;
124  }
125  };
126 
127 }
const char SPACE
Definition: io.h:46
void ringmesh_unused(const T &)
Definition: common.h:105
auto to_underlying_type(Enum e) -> typename std::underlying_type< Enum >::type
Definition: types.h:114
const char EOL
Definition: io.h:45