OpenWalnut  1.5.0dev
WMReadAmiraMesh.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 <fstream>
26 #include <memory>
27 #include <string>
28 #include <utility>
29 #include <vector>
30 
31 #include "WMReadAmiraMesh.h"
32 #include "WMReadAmiraMesh.xpm"
33 #include "core/common/WIOTools.h"
34 #include "core/common/WPathHelper.h"
35 #include "core/dataHandler/WDataSetFiberVector.h"
36 #include "core/dataHandler/WDataSetFibers.h"
37 #include "core/kernel/WKernel.h"
38 
39 // This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here.
40 W_LOADABLE_MODULE( WMReadAmiraMesh )
41 
43  WModule()
44 {
45 }
46 
48 {
49  // Cleanup!
50 }
51 
52 std::shared_ptr< WModule > WMReadAmiraMesh::factory() const
53 {
54  return std::shared_ptr< WModule >( new WMReadAmiraMesh() );
55 }
56 
57 const char** WMReadAmiraMesh::getXPMIcon() const
58 {
59  return WMReadAmiraMesh_xpm;
60 }
61 const std::string WMReadAmiraMesh::getName() const
62 {
63  return "Read Amira Mesh";
64 }
65 
66 const std::string WMReadAmiraMesh::getDescription() const
67 {
68  return "Read AmiraMesh file format. At the moment only spatial graphs are supported.";
69 }
70 
72 {
73  m_output = std::shared_ptr< WModuleOutputData< WDataSetFibers > >( new WModuleOutputData< WDataSetFibers >(
74  shared_from_this(), "out", "A loaded dataset." ) );
75 
77 
79 }
80 
82 {
83  m_propCondition = std::shared_ptr< WCondition >( new WCondition() );
84  m_dataFile = m_properties->addProperty( "Filename", "", WPathHelper::getAppPath(), m_propCondition );
85 
87 }
88 
90 {
91  // Put the code for your requirements here. See "src/modules/template/" for an extensively documented example.
92 }
93 
95 {
97  ready();
98  while( !m_shutdownFlag() )
99  {
101 
102  if( m_shutdownFlag() )
103  {
104  break;
105  }
106 
107  bool readingSuccessful = readAmiraMesh( m_dataFile->get().string() );
108  if( readingSuccessful )
109  {
110  prepareResult();
111  }
112  }
113 }
114 
116 {
117  std::shared_ptr< std::vector< WFiber > > fibs( new std::vector< WFiber > );
118  size_t globalPointId = 0;
119  for( size_t edgeId = 0; edgeId < m_edges.size(); ++edgeId )
120  {
121  std::vector< WPosition > fiberPoints;
122  for( size_t localPointId = 0; localPointId < m_numEdgePoints[edgeId]; ++localPointId )
123  {
124  fiberPoints.push_back( m_edgePoints[globalPointId] );
125  ++globalPointId;
126  }
127 
128  fibs->push_back( WFiber( fiberPoints ) );
129  }
130  WDataSetFiberVector fibersVector( fibs );
131  m_graph = std::shared_ptr< WDataSetFibers >( fibersVector.toWDataSetFibers() );
132  m_output->updateData( m_graph );
133 }
134 
135 bool checkVersionString( std::string line )
136 {
137  return line == "# AmiraMesh 3D ASCII 2.0";
138 }
139 
140 size_t parseDefine( std::string line )
141 {
142  std::vector< std::string > tokens = string_utils::tokenize( line );
143  return string_utils::fromString< double >( tokens[2] );
144 }
145 
146 void skipEmptyAndCommentLines( std::ifstream* data, std::string* line )
147 {
148  getline( *data, *line );
149  while( *line == std::string("") || (*line)[0] == '#' )
150  {
151  getline( *data, *line );
152  }
153 }
154 
155 bool parseParameters( std::ifstream* data, std::string* line )
156 {
157  bool contenTypeIsHxSpatialGraph = false;
158  while( *line != std::string( "}" ) )
159  {
160  if( line->find( "ContentType" ) != std::string::npos
161  && line->find( "HxSpatialGraph" ) != std::string::npos )
162  {
163  contenTypeIsHxSpatialGraph = true;
164  }
165 
166  getline( *data, *line );
167  }
168  return contenTypeIsHxSpatialGraph;
169 }
170 
171 void findStartLabel( const std::string& startLabel, std::ifstream* dataStream )
172 {
173  std::string tmp;
174  while( tmp.find( startLabel ) != 0 )
175  {
176  getline( *dataStream, tmp );
177  }
178 }
179 
180 void WMReadAmiraMesh::findAndReadEdgePoints( std::string startLabel, size_t numPoints, std::string fileName )
181 {
182  std::ifstream dataStream( fileName.c_str() );
183  findStartLabel( startLabel, &dataStream );
184 
185  m_edgePoints.resize( numPoints );
186  for( size_t pointId = 0; pointId < numPoints; ++pointId )
187  {
188  dataStream >> m_edgePoints[pointId][0] >> m_edgePoints[pointId][1] >> m_edgePoints[pointId][2];
189  }
190 }
191 
192 void WMReadAmiraMesh::findAndReadNumEdgePoints( std::string startLabel, size_t numEdges, std::string fileName )
193 {
194  std::ifstream dataStream( fileName.c_str() );
195  findStartLabel( startLabel, &dataStream );
196 
197  m_numEdgePoints.resize( numEdges );
198  for( size_t edgeId = 0; edgeId < numEdges; ++edgeId )
199  {
200  dataStream >> m_numEdgePoints[edgeId];
201  }
202 }
203 
204 
205 void WMReadAmiraMesh::findAndReadEdgeConnectivity( std::string startLabel, size_t numConnections, std::string fileName )
206 {
207  std::ifstream dataStream( fileName.c_str() );
208  findStartLabel( startLabel, &dataStream );
209 
210  std::pair< size_t, size_t > edge;
211  m_edges.clear();
212  for( size_t edgeId = 0; edgeId < numConnections; ++edgeId )
213  {
214  dataStream >> edge.first >> edge.second;
215  m_edges.push_back( edge );
216  }
217 }
218 
219 void WMReadAmiraMesh::findAndReadVertices( std::string startLabel, size_t numVertices, std::string fileName )
220 {
221  std::ifstream dataStream( fileName.c_str() );
222  findStartLabel( startLabel, &dataStream );
223 
224  WPosition vertex;
225  m_vertices.clear();
226  for( size_t vertexId = 0; vertexId < numVertices; ++vertexId )
227  {
228  dataStream >> vertex[0] >> vertex[1] >> vertex[2];
229  m_vertices.push_back( vertex );
230  }
231 }
232 
233 
234 bool WMReadAmiraMesh::readAmiraMesh( std::string fileName )
235 {
236  std::ifstream dataFile( fileName.c_str() );
237 
238  if( dataFile && fileExists( fileName ) )
239  {
240  WLogger::getLogger()->addLogMessage( "opening file", "Read Amira Mesh", LL_DEBUG );
241  }
242  else
243  {
244  WLogger::getLogger()->addLogMessage( "open file failed" + fileName , "Read Amira Mesh", LL_ERROR );
245  return false;
246  }
247 
248  std::string tmp;
249  getline( dataFile, tmp );
250  if( !checkVersionString( tmp ) )
251  {
252  return false;
253  }
254 
255  skipEmptyAndCommentLines( &dataFile, &tmp );
256 
257  std::vector< size_t > dimensions;
258  while( tmp.find( "define " ) == 0 )
259  {
260  dimensions.push_back( parseDefine( tmp ) );
261  getline( dataFile, tmp );
262  }
263 
264  skipEmptyAndCommentLines( &dataFile, &tmp );
265 
266  if( tmp.find( "Parameters {" ) == 0 )
267  {
268  if( !parseParameters( &dataFile, &tmp ) )
269  {
270  return false;
271  }
272  }
273  else
274  {
275  return false;
276  }
277 
278 //#warning use information about defines
279  std::string startLabelVertices = "@1";
280  findAndReadVertices( startLabelVertices, dimensions[0], fileName );
281 
282 //#warning use information about defines
283  std::string startLabelEdgeConnectivity = "@2";
284  findAndReadEdgeConnectivity( startLabelEdgeConnectivity, dimensions[1], fileName );
285 
286 //#warning use information about defines
287  std::string startLabelNumEdgePoints = "@3";
288  findAndReadNumEdgePoints( startLabelNumEdgePoints, dimensions[1], fileName );
289 
290 //#warning use information about defines
291  std::string startLabelEdgePoints = "@4";
292  findAndReadEdgePoints( startLabelEdgePoints, dimensions[2], fileName );
293 
294  return true;
295 }
virtual void wait() const
Wait for the condition.
virtual void add(std::shared_ptr< WCondition > condition)
Adds another condition to the set of conditions to wait for.
Class to encapsulate boost::condition_variable_any.
Definition: WCondition.h:42
Represents a simple set of WFibers.
std::shared_ptr< WDataSetFibers > toWDataSetFibers() const
Convert this dataset into WDataSetFibers format for other purposes if needed.
Represents a neural pathway.
Definition: WFiber.h:40
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
Reader for amiraMesh (.am) files.
std::vector< size_t > m_numEdgePoints
Number "points" per edge.
void findAndReadNumEdgePoints(std::string startLabel, size_t numEdges, std::string fileName)
Function for reading number of edgepoints per edge.
virtual const std::string getDescription() const
Gives back a description of this module.
WPropFilename m_dataFile
The data will be read from this file.
std::vector< WPosition > m_vertices
vertices of the spatial graph
std::shared_ptr< WDataSetFibers > m_graph
The resulting fiber dataset respresenting the spatial graph.
std::vector< WPosition > m_edgePoints
The positions of the points building the edges between the vertices.
virtual ~WMReadAmiraMesh()
Destructor for cleaning up resources.
virtual std::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
virtual const std::string getName() const
Gives back the name of this module.
virtual void moduleMain()
Entry point after loading the module.
bool readAmiraMesh(std::string fileName)
Very prelimiary and specialized way of reading a spatial graph from an amira mesh.
virtual void requirements()
Initialize requirements for this module.
void findAndReadEdgeConnectivity(std::string startLabel, size_t numConnections, std::string fileName)
Function for reading connectivity of edges.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
void prepareResult()
This function prepares the resulting dataset for being provided at the connector by construting it fr...
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
std::vector< std::pair< size_t, size_t > > m_edges
Edge connectivity of the spatial graph.
virtual void properties()
Initialize the properties for this module.
WMReadAmiraMesh()
Standard constructor.
virtual void connectors()
Initialize the connectors this module is using.
std::shared_ptr< WModuleOutputData< WDataSetFibers > > m_output
The only output of this data module.
void findAndReadEdgePoints(std::string startLabel, size_t numPoints, std::string fileName)
Function for reading edgepoints.
void findAndReadVertices(std::string startLabel, size_t numVertices, std::string fileName)
Function for reading coordinates of vertices.
Class offering an instantiate-able data connection between modules.
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
virtual void properties()
Initialize properties in this function.
Definition: WModule.cpp:212
void addConnector(std::shared_ptr< WModuleInputConnector > con)
Adds the specified connector to the list of inputs.
Definition: WModule.cpp:108
std::shared_ptr< WProperties > m_properties
The property object for the module.
Definition: WModule.h:640
void ready()
Call this whenever your module is ready and can react on property changes.
Definition: WModule.cpp:505
WConditionSet m_moduleState
The internal state of the module.
Definition: WModule.h:703
virtual void connectors()
Initialize connectors in this function.
Definition: WModule.cpp:208
static boost::filesystem::path getAppPath()
The path where the binary file resides in.
Definition: WPathHelper.cpp:93
This only is a 3d double vector.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
std::vector< std::string > tokenize(const std::string &source, const std::string &delim=WHITESPACE, bool compress=true)
Splits the given string into a vector of strings (so called tokens).