OpenWalnut  1.5.0dev
WMFiberFilterIndex.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 <algorithm>
26 #include <memory>
27 #include <string>
28 #include <vector>
29 
30 #include "WMFiberFilterIndex.h"
31 #include "core/kernel/WKernel.h"
32 
33 // This line is needed by the module loader to actually find your module. You need to add this to your module too. Do NOT add a ";" here.
34 W_LOADABLE_MODULE( WMFiberFilterIndex )
35 
37  WModule()
38 {
39  // Init
40 }
41 
43 {
44  // Cleanup!
45 }
46 
47 std::shared_ptr< WModule > WMFiberFilterIndex::factory() const
48 {
49  return std::shared_ptr< WModule >( new WMFiberFilterIndex() );
50 }
51 
52 const std::string WMFiberFilterIndex::getName() const
53 {
54  // Specify your module name here. This name must be UNIQUE!
55  return "Fiber Filter Index";
56 }
57 
58 const std::string WMFiberFilterIndex::getDescription() const
59 {
60  // Specify your module description here. Be detailed. This text is read by the user.
61  return "This module provides fiber data filtered by fiber index.";
62 }
63 
65 {
66  m_input = WModuleInputData< WDataSetFibers >::createAndAdd( shared_from_this(), "in", "The dataset to filter" );
67  m_output = WModuleOutputData < WDataSetFibers >::createAndAdd( shared_from_this(), "out", "The filtered dataset" );
68 
69  // call WModule's initialization
71 }
72 
74 {
75  m_propCondition = std::shared_ptr< WCondition >( new WCondition() );
76  m_indexProp = m_properties->addProperty( "Index", "Select the fiber with this index.", 0, m_propCondition );
77  m_indexProp->setMin( 0 );
78  m_indexProp->setMax( 1 );
79 
81 }
82 
84 {
85  m_moduleState.setResetable( true, true );
86  m_moduleState.add( m_input->getDataChangedCondition() );
88 
89  // Signal ready state. Now your module can be connected by the container, which owns the module.
90  ready();
91  waitRestored();
92 
93  // main loop
94  while( !m_shutdownFlag() )
95  {
97 
98  // woke up since the module is requested to finish
99  if( m_shutdownFlag() )
100  {
101  break;
102  }
103 
104  // Remember the above criteria. We now need to check if the data is valid. After a connect-update, it might be NULL.
105  std::shared_ptr< WDataSetFibers > dataSet = m_input->getData();
106  bool dataValid = ( dataSet != NULL );
107  bool dataChanged = dataSet != m_fibers;
108 
109  // do something with the data
110  if( dataChanged )
111  {
112  m_fibers = dataSet;
113 
114  if( dataValid )
115  {
116  // The data is valid and we received an update. The data is not NULL but may be the same as in previous loops.
117  debugLog() << "Data changed. Recalculating output.";
118  m_indexProp->setMax( m_fibers->size() - 1 );
119  updateOutput();
120  }
121  }
122 
123  if( m_indexProp->changed( true ) )
124  {
125  updateOutput();
126  }
127  }
128 }
129 
131 {
132  // target memory
133  std::shared_ptr< std::vector< float > > vertices( new std::vector< float >() );
134  std::shared_ptr< std::vector< size_t > > lineStartIndexes( new std::vector< size_t >() );
135  std::shared_ptr< std::vector< size_t > > lineLengths( new std::vector< size_t >() );
136  std::shared_ptr< std::vector< size_t > > verticesReverse( new std::vector< size_t >() );
137  WDataSetFibers::VertexParemeterArray vertexParameter;
138 
139  std::shared_ptr< WProgress > progress1( new WProgress( "Filtering" ) );
140  m_progress->addSubProgress( progress1 );
141 
142  size_t idx = m_indexProp->get( true );
143 
144  // Valid index?
145  if( idx >= m_fibers->size() )
146  {
147  errorLog() << "Index invalid: " << idx << " - data has only " << m_fibers->size() << " lines.";
148  m_output->reset();
149  }
150 
151  // Is there an parameter array defined in the source data?
152  bool hasAttribs = ( m_fibers->getVertexParameters() != NULL );
153 
154  // Get vertex data
155  size_t startIdx =m_fibers->getStartIndex( idx );
156  size_t startIdx3 = 3 * startIdx;
157  size_t len = m_fibers->getLengthOfLine( idx );
158  size_t len3 = 3 * len;
159 
160  // Copy vertex data
161  vertices->resize( len * 3 );
162  std::copy( m_fibers->getVertices()->begin() + startIdx3, m_fibers->getVertices()->begin() + startIdx3 + len3, vertices->begin() );
163 
164  // Copy attrib data if any
165  if( hasAttribs )
166  {
167  vertexParameter = WDataSetFibers::VertexParemeterArray( new WDataSetFibers::VertexParemeterArray::element_type( len ) );
168  std::copy( m_fibers->getVertexParameters()->begin() + startIdx, m_fibers->getVertexParameters()->begin() + startIdx + len,
169  vertexParameter->begin() );
170  }
171 
172  // As the fiber display has problems with data with less than 3 vertices -> ensure 3
173  if( len == 2 )
174  {
175  len = 3;
176 
177  // Use the last vertex again -> visually not visible.
178  vertices->push_back( vertices->at( 3 ) );
179  vertices->push_back( vertices->at( 4 ) );
180  vertices->push_back( vertices->at( 5 ) );
181 
182  if( hasAttribs )
183  {
184  vertexParameter->push_back( vertexParameter->at( 1 ) );
185  }
186  }
187 
188  // the remaining info is trivial
189  lineStartIndexes->push_back( 0 );
190  lineLengths->push_back( len );
191  verticesReverse->resize( len, 0 );
192 
193  // Update output and finish
194  std::shared_ptr< WDataSetFibers> newOutput( new WDataSetFibers( vertices, lineStartIndexes, lineLengths, verticesReverse, vertexParameter ) );
195  m_output->updateData( newOutput );
196 
197  progress1->finish();
198 }
virtual void wait() const
Wait for the condition.
void setResetable(bool resetable=true, bool autoReset=true)
Sets the resetable flag.
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< std::vector< double > > VertexParemeterArray
Parameter storage for each vertex.
This module is intended to allow the user to filter a fiber dataset using the current ROI config.
void updateOutput()
Updates the output using the ROI configuration.
std::shared_ptr< WModuleOutputData< WDataSetFibers > > m_output
The output connector for the filtered data.
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...
WDataSetFibers::SPtr m_fibers
Fiber data.
virtual const std::string getDescription() const
Gives back a description of this module.
virtual const std::string getName() const
Gives back the name of this module.
std::shared_ptr< WModuleInputData< WDataSetFibers > > m_input
An input for the fiber data.
virtual void properties()
Initialize the properties for this module.
virtual void moduleMain()
Entry point after loading the module.
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
virtual void connectors()
Initialize the connectors this module is using.
WMFiberFilterIndex()
Default constructor.
WPropInt m_indexProp
Trigger output update.
virtual ~WMFiberFilterIndex()
Destructor.
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 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
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
std::shared_ptr< WProgressCombiner > m_progress
Progress indicator used as parent for all progress' of this module.
Definition: WModule.h:652
virtual void connectors()
Initialize connectors in this function.
Definition: WModule.cpp:208
void waitRestored()
This method waits for the module to be restored completely.
Definition: WModule.cpp:625
Class managing progress inside of modules.
Definition: WProgress.h:42
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.