OpenWalnut  1.5.0dev
WMeshReaderVTK.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <memory>
26 #include <string>
27 #include <vector>
28 
29 #include "WMeshReaderVTK.h"
30 
32  WObjectNDIP< WMeshReaderInterface >( "VTK", "Load VTK Meshes." )
33 {
34  // add properties
35  m_propVectorAsColor = m_properties->addProperty( "Read vectors as color",
36  "If the module can load vectors from the file "
37  "it will interpret them as colors of the surface.",
38  true );
39 }
40 
42 {
43  // cleanup
44 }
45 
47  boost::filesystem::path file )
48 {
49  namespace su = string_utils;
50 
51  std::string fileName = file.string();
52  WAssert( !fileName.empty(), "No filename specified." );
53 
54  std::shared_ptr< WProgress > progress( new WProgress( "Read Mesh", 3 ) );
55  parentProgress->addSubProgress( progress );
56 
57  std::ifstream ifs;
58  ifs.open( fileName.c_str(), std::ifstream::in );
59  if( !ifs || ifs.bad() )
60  {
61  WLogger::getLogger()->addLogMessage( "Try load broken file '" + fileName + "'", "Read Mesh", LL_ERROR );
62  throw std::runtime_error( "Problem during reading file. Probably file not found." );
63  }
64  std::string line;
65 
66  // ------ HEADER -------
67  std::vector< std::string > header;
68  for( int i = 0; i < 4; ++i ) // strip first four lines
69  {
70  std::getline( ifs, line );
71  if( !ifs.good() )
72  {
73  WLogger::getLogger()->addLogMessage( "Unexpected end of file: " + fileName, "Read Mesh", LL_ERROR );
74  progress->finish();
75  return std::shared_ptr< WTriangleMesh >();
76  }
77  header.push_back( line );
78  }
79  if( header.at( 0 ) != "# vtk DataFile Version 2.0" )
80  {
81  WLogger::getLogger()->addLogMessage( "Unsupported format version string: " + header.at( 0 ), "Read Mesh", LL_WARNING );
82  }
83 
84  if( su::toUpper( su::trim( header.at( 2 ) ) ) != "ASCII" )
85  {
86  WLogger::getLogger()->addLogMessage( "Only ASCII files supported, not " + header.at( 2 ), "Read Mesh", LL_ERROR );
87  progress->finish();
88  return std::shared_ptr< WTriangleMesh >();
89  }
90 
91  if( su::tokenize( header.at( 3 ) ).size() < 2 ||
92  su::toUpper( su::tokenize( header.at( 3 ) )[1] ) != "UNSTRUCTURED_GRID" )
93  {
94  WLogger::getLogger()->addLogMessage( "Invalid VTK DATASET type: " + su::tokenize( header.back() )[1], "Read Mesh", LL_ERROR );
95  progress->finish();
96  return std::shared_ptr< WTriangleMesh >();
97  }
98 
99  // ------ POINTS -------
100 
101  std::getline( ifs, line );
102  size_t numPoints = 0;
103  std::vector< std::string > tokens = su::tokenize( line );
104  if( tokens.size() != 3 || su::toLower( tokens.at( 2 ) ) != "float" || su::toLower( tokens.at( 0 ) ) != "points" )
105  {
106  WLogger::getLogger()->addLogMessage( "Invalid VTK POINTS declaration: " + line, "Read Mesh", LL_ERROR );
107  progress->finish();
108  return std::shared_ptr< WTriangleMesh >();
109  }
110  try
111  {
112  numPoints = string_utils::fromString< size_t >( tokens.at( 1 ) );
113  }
114  catch( const std::exception &e )
115  {
116  WLogger::getLogger()->addLogMessage( "Invalid number of points: " + tokens.at( 1 ), "Read Mesh", LL_ERROR );
117  progress->finish();
118  return std::shared_ptr< WTriangleMesh >();
119  }
120 
121 
122  std::vector< WPosition > points;
123  points.reserve( numPoints );
124  float pointData[3];
125  for( unsigned int i = 0; i < numPoints; ++i )
126  {
127  ifs >> pointData[0] >> pointData[1] >> pointData[2];
128  points.push_back( WPosition( pointData[0], pointData[1], pointData[2] ) );
129  }
130 
131  // ----- Vertex Ids For Cells---------
132  char* cellsMarker = new char[30];
133  size_t nbCells;
134  size_t nbNumbers;
135  ifs >> cellsMarker >> nbCells >> nbNumbers;
136 
137  std::shared_ptr< WTriangleMesh > triMesh( new WTriangleMesh( numPoints, nbCells ) );
138 
139  for( unsigned int i = 0; i < numPoints; ++i )
140  {
141  triMesh->addVertex( osg::Vec3( points[i][0], points[i][1], points[i][2] ) );
142  }
143  ++*progress;
144 
145  unsigned int nbCellVerts;
146  for( unsigned int i = 0; i < nbCells; ++i )
147  {
148  unsigned int tri[3];
149  ifs >> nbCellVerts >> tri[0] >> tri[1] >> tri[2];
150  triMesh->addTriangle( tri[0], tri[1], tri[2] );
151  if( nbCellVerts != 3 )
152  {
153  WLogger::getLogger()->addLogMessage( "Number of cell vertices should be 3 but found " +
154  string_utils::toString( nbCellVerts ) + ".", "Read Mesh", LL_ERROR );
155  progress->finish();
156  return std::shared_ptr< WTriangleMesh >();
157  }
158  }
159 
160  ++*progress;
161 
162  // ----- Cell Types ---------
163  char* cells_typesMarker = new char[30];
164  size_t nbCellTypes;
165  ifs >> cells_typesMarker >> nbCellTypes;
166  unsigned int cellType;
167  for( unsigned int i = 0; i < nbCellTypes; ++i )
168  {
169  ifs >> cellType;
170  if( cellType != 5 )
171  {
172  WLogger::getLogger()->addLogMessage( "Invalid cell type: " + string_utils::toString( cellType ) + ".", "Read Mesh", LL_ERROR );
173  progress->finish();
174  return std::shared_ptr< WTriangleMesh >();
175  }
176  }
177 
178  char* marker = new char[30];
179  size_t nbVectors;
180  ifs >> marker >> nbVectors;
181  if( std::string( marker ) == "POINT_DATA" && nbVectors == numPoints )
182  {
183  // ----- Vector as color ---------
184  char* vectorMarker = new char[30];
185  char* vectorName = new char[30];
186  char* vectorInfo1 = new char[30];
187  char* vectorInfo2 = new char[30];
188  ifs >> vectorMarker >> vectorName >> vectorInfo1 >> vectorInfo2;
189 
190  if( std::string( vectorMarker ) == "VECTORS"
191  && m_propVectorAsColor->get()
192  && std::string( vectorInfo1 ) == "float" )
193  {
194  WLogger::getLogger()->addLogMessage( "Reading colors from vectors", "Read Mesh", LL_DEBUG );
195  WColor vectorComp;
196  for( unsigned int i = 0; i < nbVectors; ++i )
197  {
198  std::string line;
199  std::getline( ifs, line, '\n' );
200  ifs >> vectorComp[0] >> vectorComp[1] >> vectorComp[2];
201  triMesh->setVertexColor( i, vectorComp );
202  }
203  }
204  if( std::string( vectorMarker ) == "ARRAYS" )
205  {
206  //WLogger::getLogger()->addLogMessage( std::string( vectorInfo1[0] ), "Read Mesh", LL_DEBUG );
207  WAssert( vectorInfo1[0] == '2' || vectorInfo1[0] == '3', "Can only deal with 2D or 3D arrays." );
208  if( m_propVectorAsColor->get()
209  && std::string( vectorInfo2 ) == "float" )
210  {
211  WLogger::getLogger()->addLogMessage( "Reading colors from arrays", "Read Mesh", LL_DEBUG );
212  WColor vectorComp;
213  for( unsigned int i = 0; i < nbVectors; ++i )
214  {
215  std::string line;
216  std::getline( ifs, line, '\n' );
217  if( vectorInfo1[0] == '2' )
218  {
219  ifs >> vectorComp[0] >> vectorComp[1];
220  vectorComp[2] = 0;
221  }
222  if( vectorInfo1[0] == '3' )
223  {
224  ifs >> vectorComp[0] >> vectorComp[1] >> vectorComp[2];
225  }
226  triMesh->setVertexColor( i, vectorComp );
227  }
228  }
229  }
230  triMesh->rescaleVertexColors();
231  delete[] vectorMarker;
232  delete[] vectorName;
233  delete[] vectorInfo1;
234  delete[] vectorInfo2;
235  }
236 
237  ifs.close();
238 
239  progress->finish();
240 
241  delete[] cellsMarker;
242  delete[] cells_typesMarker;
243  delete[] marker;
244 
245  return triMesh;
246 }
void addLogMessage(std::string message, std::string source="", LogLevel level=LL_DEBUG)
Appends a log message to the logging queue.
Definition: WLogger.cpp:84
static WLogger * getLogger()
Returns pointer to the currently running logger instance.
Definition: WLogger.cpp:64
Define the interface which is injected into an WObjectNDIP.
WMeshReaderVTK()
Constructor.
virtual WTriangleMesh::SPtr operator()(WProgressCombiner::SPtr parentProgress, boost::filesystem::path file)
Load the dataset.
virtual ~WMeshReaderVTK()
Destructor.
WPropBool m_propVectorAsColor
Use vectors from file as color of surface.
This is a base class for everything which has a Name,Description,Icon and Properties (=NDIP).
Definition: WObjectNDIP.h:42
WProperties::SPtr m_properties
the properties of the object.
Definition: WObjectNDIP.h:99
This only is a 3d double vector.
std::shared_ptr< WProgressCombiner > SPtr
Abbreviate shared_ptr for this class.
Class managing progress inside of modules.
Definition: WProgress.h:42
Triangle mesh data structure allowing for convenient access of the elements.
Definition: WTriangleMesh.h:46
std::shared_ptr< WTriangleMesh > SPtr
Shared pointer.
Definition: WTriangleMesh.h:55
Some utilities for string manipulation and output operations.
Definition: WStringUtils.h:59
std::string toString(const T &value)
Convert a given value to a string.
Definition: WStringUtils.h:120