OpenWalnut  1.5.0dev
WMWriteAmiraMesh.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2013 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 
28 #include "WMWriteAmiraMesh.h"
29 #include "core/common/datastructures/WFiber.h"
30 #include "core/kernel/WKernel.h"
31 
32 // This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here.
33 W_LOADABLE_MODULE( WMWriteAmiraMesh )
34 
35 WMWriteAmiraMesh::WMWriteAmiraMesh():
36  WModule()
37 {
38 }
39 
40 WMWriteAmiraMesh::~WMWriteAmiraMesh()
41 {
42  // Cleanup!
43 }
44 
45 std::shared_ptr< WModule > WMWriteAmiraMesh::factory() const
46 {
47  // See "src/modules/template/" for an extensively documented example.
48  return std::shared_ptr< WModule >( new WMWriteAmiraMesh() );
49 }
50 
51 const std::string WMWriteAmiraMesh::getName() const
52 {
53  return "Write Amira Mesh";
54 }
55 
56 const std::string WMWriteAmiraMesh::getDescription() const
57 {
58  return "Write AmiraMesh file format. At the moment only line sets are supported.";
59 }
60 
62 {
63  // Put the code for your connectors here. See "src/modules/template/" for an extensively documented example.
64  m_tractConnector = WModuleInputData< const WDataSetFibers >::createAndAdd( shared_from_this(), "tractInput", "A dataset of tracts" );
65 
67 }
68 
70 {
71  // Put the code for your properties here. See "src/modules/template/" for an extensively documented example.
72 
73  m_savePath = m_properties->addProperty( "Save Path", "Where to save the result", boost::filesystem::path( "/no/such/file" ) );
75  m_run = m_properties->addProperty( "Save", "Start saving", WPVBaseTypes::PV_TRIGGER_READY );
77 }
78 
80 {
81 }
82 
84 {
85  m_moduleState.add( m_tractConnector->getDataChangedCondition() );
86  m_moduleState.add( m_run->getCondition() );
87 
88  ready();
89 
90  while( !m_shutdownFlag() )
91  {
93 
94  if( !m_tractConnector->getData() )
95  {
96  continue;
97  }
98 
99  if( m_run->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
100  {
101  writeFile();
103  }
104  }
105 }
106 
108 {
109  // open file
110  boost::filesystem::path meshFile( m_savePath->get() );
111  std::string fnPath = meshFile.string();
112 
113  debugLog() << "Opening " << fnPath << " for writing.";
114  std::ofstream dataFile( fnPath.c_str(), std::ios_base::binary );
115  if( !dataFile )
116  {
117  errorLog() << "Opening " << fnPath << " failed.";
118  return;
119  }
120 
121  // needed arrays for iterating the fibers
122  // WDataSetFibers::IndexArray fibStart = fibers->getLineStartIndexes();
123  WDataSetFibers::LengthArray fibLen = m_tractConnector->getData()->getLineLengths();
124  WDataSetFibers::VertexArray fibVerts = m_tractConnector->getData()->getVertices();
125  //WDataSetFibers::TangentArray fibTangents = fibers->getTangents();
126 
127  std::size_t numPoints = fibVerts->size() / 3;
128 
129  debugLog() << "Writing ...";
130 
131  // write some head data
132  dataFile << "# AmiraMesh 3D ASCII 2.0" << std::endl << std::endl;
133 
134  dataFile << "define Lines " << numPoints + m_tractConnector->getData()->size() << std::endl;
135  dataFile << "nVertices " << numPoints << std::endl;
136  dataFile << std::endl;
137  dataFile << "Parameters {" << std::endl;
138  dataFile << " ContentType \"HxLineSet\"" << std::endl;
139  dataFile << "}" << std::endl;
140  dataFile << std::endl;
141  dataFile << "Lines { int LineIdx } @1" << std::endl;
142  dataFile << "Vertices { float[3] Coordinates } @2" << std::endl;
143  dataFile << std::endl;
144  dataFile << "# Data section follows" << std::endl;
145  dataFile << std::endl;
146  dataFile << "@1" << std::endl;
147  size_t vertCounter = 0;
148  size_t lineId = 0;
149  for( size_t vertId = 0; vertId < numPoints; ++vertId )
150  {
151  dataFile << vertId << std::endl;
152  ++vertCounter;
153  if( vertCounter == (*fibLen)[lineId] )
154  {
155  ++lineId;
156  vertCounter = 0;
157  dataFile << -1 << std::endl;
158  }
159  }
160  dataFile << std::endl;
161  dataFile << "@2" << std::endl;
162  for( size_t vertId = 0; vertId < numPoints; ++vertId )
163  {
164  dataFile << (*fibVerts)[vertId*3+0] << " " << (*fibVerts)[vertId*3+1] << " " << (*fibVerts)[vertId*3+2] << " " << std::endl;
165  }
166  debugLog() << "Writing done.";
167 }
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.
std::shared_ptr< std::vector< size_t > > LengthArray
Lengths of fibers in terms of vertices.
std::shared_ptr< std::vector< float > > VertexArray
List of vertex coordinates in term of components of vertices.
Someone should add some documentation here.
virtual const std::string getName() const
Gives back the name of this module.
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 getDescription() const
Gives back a description of this module.
virtual void requirements()
Initialize requirements for this module.
WPropTrigger m_run
Button to start saving.
std::shared_ptr< WModuleInputData< const WDataSetFibers > > m_tractConnector
Input connector for writing directly tracts to a file.
void writeFile()
Writes the data to file.
virtual void connectors()
Initialize the connectors this module is using.
virtual void properties()
Initialize the properties for this module.
virtual void moduleMain()
Entry point after loading the module.
WPropFilename m_savePath
Path where tracts should be stored.
static PtrType createAndAdd(std::shared_ptr< WModule > module, std::string name="", std::string description="")
Convenience method to create a new instance of this in data connector with proper type and add it to ...
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
virtual void properties()
Initialize properties in this function.
Definition: WModule.cpp:212
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
Definition: WModule.cpp:575
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
wlog::WStreamedLogger errorLog() const
Logger instance for comfortable error logging.
Definition: WModule.cpp:570
virtual void connectors()
Initialize connectors in this function.
Definition: WModule.cpp:208
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
@ PV_TRIGGER_TRIGGERED
Trigger property: got triggered.
@ PV_TRIGGER_READY
Trigger property: is ready to be triggered (again)
void addTo(WPropSelection prop)
Add the PC_NOTEMPTY constraint to the property.