OpenWalnut  1.5.0dev
WMVectorNormalize.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 <cmath>
26 #include <fstream>
27 #include <iostream>
28 #include <memory>
29 #include <stdint.h>
30 #include <string>
31 #include <vector>
32 
33 #include <boost/variant.hpp>
34 
35 #include "WMVectorNormalize.h"
36 #include "core/common/WAssert.h"
37 #include "core/common/WProgress.h"
38 #include "core/common/WStringUtils.h"
39 #include "core/common/WTypeTraits.h"
40 #include "core/common/exceptions/WTypeMismatch.h"
41 #include "core/dataHandler/WDataHandler.h"
42 #include "core/dataHandler/WDataHandlerEnums.h"
43 #include "core/dataHandler/WGridRegular3D.h"
44 #include "core/dataHandler/exceptions/WDHValueSetMismatch.h"
45 #include "core/kernel/WKernel.h"
46 
47 // This line is needed by the module loader to actually find your module.
48 W_LOADABLE_MODULE( WMVectorNormalize )
49 
51  WModule()
52 {
53  // initialize
54 }
55 
57 {
58  // cleanup
60 }
61 
62 std::shared_ptr< WModule > WMVectorNormalize::factory() const
63 {
64  return std::shared_ptr< WModule >( new WMVectorNormalize() );
65 }
66 
67 const std::string WMVectorNormalize::getName() const
68 {
69  return "Vector Normalize";
70 }
71 
72 const std::string WMVectorNormalize::getDescription() const
73 {
74  return "Normalize a vector field.";
75 }
76 
78 {
79  m_inputA = WModuleInputData< WDataSetVector >::createAndAdd( shared_from_this(), "input", "Input vectors." );
80 
81  m_output = WModuleOutputData< WDataSetVector >::createAndAdd( shared_from_this(), "normalized", "Normalized input." );
82 
83  // call WModules initialization
85 }
86 
88 {
89  m_propCondition = std::shared_ptr< WCondition >( new WCondition() );
90 
91  m_zeroTol = m_properties->addProperty( "Zero Tolerance", "Vector lengths smaller than this are assumed as being 0.", 0.000001, m_propCondition );
92  m_zeroTol->setMin( 0.0 );
93  m_zeroTol->setMax( 1.0 );
94 
96 }
97 
98 /**
99  * Visitor for discriminating the type of the first valueset.
100  */
101 class VisitorVSetA: public boost::static_visitor< std::shared_ptr< WValueSetBase > >
102 {
103 public:
104  /**
105  * Create visitor instance.
106  *
107  * \param zeroTol zero tollerance
108  */
109  explicit VisitorVSetA( double zeroTol ):
110  boost::static_visitor< result_type >(),
111  m_zeroTol( zeroTol )
112  {
113  }
114 
115  /**
116  * Called by boost::varying during static visiting.
117  *
118  * \tparam T the real integral type of the first value set.
119  * \param vsetA the first valueset currently visited.
120  *
121  * \return the result from the operation
122  */
123  template < typename T >
124  result_type operator()( const WValueSet< T >* const& vsetA ) const // NOLINT
125  {
126  // get some info
127  std::vector< T > data;
128  data.resize( vsetA->rawSize() );
129 
130  // apply op to each value
131  // iterate field
132  for( size_t i = 0; i < vsetA->size(); ++i )
133  {
134  // to avoid cascading numeric errors due to T being a low resolution type, we use doubles during calculation
135  double x = vsetA->getScalar( ( i * 3 ) + 0 );
136  double y = vsetA->getScalar( ( i * 3 ) + 1 );
137  double z = vsetA->getScalar( ( i * 3 ) + 2 );
138 
139  double len = sqrt( ( x * x ) + ( y * y ) + ( z * z ) );
140  if( len < m_zeroTol )
141  {
142  data[ ( i * 3 ) + 0 ] = 0;
143  data[ ( i * 3 ) + 1 ] = 0;
144  data[ ( i * 3 ) + 2 ] = 0;
145 
146  continue;
147  }
148 
149  data[ ( i * 3 ) + 0 ] = static_cast< T >( x / len );
150  data[ ( i * 3 ) + 1 ] = static_cast< T >( y / len );
151  data[ ( i * 3 ) + 2 ] = static_cast< T >( z / len );
152  }
153 
154  // create result value set
155  return std::shared_ptr< WValueSet< T > >( new WValueSet< T >( 1,
156  3,
157  std::shared_ptr< std::vector< T > >(
158  new std::vector< T >( data ) ),
160  }
161 
162  /**
163  * Zero tollerance. Values smaller than this are interpreted as zero
164  */
165  double m_zeroTol;
166 };
167 
169 {
170  // let the main loop awake if the data changes or the properties changed.
171  m_moduleState.setResetable( true, true );
172  m_moduleState.add( m_inputA->getDataChangedCondition() );
174 
175  // signal ready state
176  ready();
177 
178  // loop until the module container requests the module to quit
179  while( !m_shutdownFlag() )
180  {
181  // Now, the moduleState variable comes into play. The module can wait for the condition, which gets fired whenever the input receives data
182  // or an property changes. The main loop now waits until something happens.
183  debugLog() << "Waiting ...";
185 
186  // woke up since the module is requested to finish
187  if( m_shutdownFlag() )
188  {
189  break;
190  }
191 
192  // has the data changed?
193  if( m_zeroTol->changed() || m_inputA->handledUpdate() )
194  {
195  std::shared_ptr< WDataSetVector > dataSetA = m_inputA->getData();
196 
197  // valid data?
198  if( dataSetA )
199  {
200  std::shared_ptr< WValueSetBase > valueSetA = dataSetA->getValueSet();
201 
202  // use a custom progress combiner
203  std::shared_ptr< WProgress > prog = std::shared_ptr< WProgress >(
204  new WProgress( "Applying operator on data" ) );
205  m_progress->addSubProgress( prog );
206 
207  // apply the operation to each voxel
208  debugLog() << "Processing ...";
209  std::shared_ptr< WValueSetBase > newValueSet = valueSetA->applyFunction( VisitorVSetA( m_zeroTol->get( true ) ) );
210 
211  // Create the new dataset and export it
212  m_output->updateData( std::shared_ptr<WDataSetVector>( new WDataSetVector( newValueSet, m_inputA->getData()->getGrid() ) ) );
213 
214  // done
215  prog->finish();
216  m_progress->removeSubProgress( prog );
217  }
218  else
219  {
220  debugLog() << "Resetting output.";
221  m_output->reset();
222  }
223  }
224  }
225 }
226 
Visitor for discriminating the type of the first valueset.
result_type operator()(const WValueSet< T > *const &vsetA) const
Called by boost::varying during static visiting.
double m_zeroTol
Zero tollerance.
VisitorVSetA(double zeroTol)
Create visitor instance.
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
This data set type contains vectors as values.
Operator for normalizing vectors.
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.
std::shared_ptr< WModuleOutputData< WDataSetVector > > m_output
The only output of this filter module.
virtual void properties()
Initialize the properties for this module.
virtual const std::string getName() const
Gives back the name of this module.
virtual const std::string getDescription() const
Gives back a description of this module.
~WMVectorNormalize()
Destructor.
std::shared_ptr< WModuleInputData< WDataSetVector > > m_inputA
Input connector required by this module.
virtual void moduleMain()
Entry point after loading the module.
WPropDouble m_zeroTol
Zero Tollerance.
WMVectorNormalize()
Standard constructor.
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...
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 ...
static PtrType createAndAdd(std::shared_ptr< WModule > module, std::string name="", std::string description="")
Convenience method to create a new instance of this out 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
void removeConnectors()
Removes all connectors properly.
Definition: WModule.cpp:194
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
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
Class managing progress inside of modules.
Definition: WProgress.h:42
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
Base Class for all value set types.
Definition: WValueSet.h:47
An object that knows an appropriate dataType flag for the typename T.