OpenWalnut  1.5.0dev
WMVectorPlot.h
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 #ifndef WMVECTORPLOT_H
26 #define WMVECTORPLOT_H
27 
28 #include <memory>
29 #include <string>
30 #include <vector>
31 
32 #include <osg/Geode>
33 #include <osg/Geometry>
34 
35 #include "core/common/math/linearAlgebra/WPosition.h"
36 #include "core/dataHandler/WDataSetVector.h"
37 #include "core/graphicsEngine/shaders/WGEShader.h"
38 #include "core/kernel/WKernel.h"
39 #include "core/kernel/WModule.h"
40 #include "core/kernel/WModuleInputData.h"
41 #include "core/kernel/WModuleOutputData.h"
42 
43 /**
44  * Show an glyph plot (in this case the glyphs are arrows) of a vector data set.
45  * \ingroup modules
46  */
47 class WMVectorPlot: public WModule
48 {
49 public:
50  /**
51  * Default constructor.
52  */
53  WMVectorPlot();
54 
55  /**
56  * Destructor.
57  */
58  virtual ~WMVectorPlot();
59 
60  /**
61  * Gives back the name of this module.
62  * \return the module's name.
63  */
64  virtual const std::string getName() const;
65 
66  /**
67  * Gives back a description of this module.
68  * \return description to module.
69  */
70  virtual const std::string getDescription() const;
71 
72  /**
73  * Due to the prototype design pattern used to build modules, this method returns a new instance of this method. NOTE: it
74  * should never be initialized or modified in some other way. A simple new instance is required.
75  *
76  * \return the prototype used to create every module in OpenWalnut.
77  */
78  virtual std::shared_ptr< WModule > factory() const;
79 
80  /**
81  * Get the icon for this module in XPM format.
82  * \return The icon.
83  */
84  virtual const char** getXPMIcon() const;
85 
86 protected:
87  /**
88  * Entry point after loading the module. Runs in separate thread.
89  */
90  virtual void moduleMain();
91 
92  /**
93  * Initialize the connectors this module is using.
94  */
95  virtual void connectors();
96 
97  /**
98  * Initialize the properties for this module.
99  */
100  virtual void properties();
101 
102  /**
103  * The root node used for this modules graphics. For OSG nodes, always use osg::ref_ptr to ensure proper resource management.
104  */
105  osg::ref_ptr<osg::Geode> m_rootNode;
106 
107  /**
108  * Callback for m_active. Overwrite this in your modules to handle m_active changes separately.
109  */
110  virtual void activate();
111 
112 private:
113  /**
114  * Creates a vector plot on the currently selected slices.
115  *
116  * \return geometry containing the slices
117  * \tparam ValueType the real type of the valueset
118  */
119  template< typename ValueType >
120  osg::ref_ptr<osg::Geometry> buildPlotSlices();
121 
122  /**
123  * Creates a vector plot on the currently selected slices. Handles valuesets of different types properly.
124  *
125  * \return geometry containing the slices
126  */
127  osg::ref_ptr<osg::Geometry> buildPlotSlices();
128 
129  /**
130  * The update callback that is called for the osg node of this module.
131  */
132  void updateCallback();
133 
134  /**
135  * Transforms the given vertices according to m_matrix
136  * \param verts These vertices will be transformed.
137  */
138  void transformVerts( osg::ref_ptr< osg::Vec3Array > verts );
139 
140  /**
141  * An input connector used to get datasets from other modules. The connection management between connectors must not be handled by the module.
142  */
143  std::shared_ptr< WModuleInputData< WDataSetVector > > m_input;
144 
145  /**
146  * This is a pointer to the dataset the module is currently working on.
147  */
148  std::shared_ptr< WDataSetVector > m_dataSet;
149 
150  /**
151  * list of positions to plot vectors on, this will come from a selection tool class
152  */
153  std::shared_ptr< std::vector< WPosition > > m_positions;
154 
155  WPropBool m_projectOnSlice; //!< projects the vectors on the slice.
156 
157  WPropBool m_coloringMode; //!< indicates a set color or direction color coding.
158 
159  WPropDouble m_xSlice; //!< x position of the slice
160 
161  WPropDouble m_ySlice; //!< y position of the slice
162 
163  WPropDouble m_zSlice; //!< z position of the slice
164 
165  WPropBool m_showOnSagittal; //!< indicates whether the vector should be shown on sagittal slice
166 
167  WPropBool m_showOnCoronal; //!< indicates whether the vector should be shown on coronal slice
168 
169  WPropBool m_showOnAxial; //!< indicates whether the vector should be shown on axial slice
170 
171 
172  WPropColor m_aColor; //!< color
173 
174  WPropDouble m_scale; //!< Scaling of arrow length.
175 
176  osg::ref_ptr< WGEShader > m_shader; //!< the shader object for this module
177 
178  WPosition m_oldPos; //!< The previous position of the slides.
179 };
180 
181 template< typename ValueType >
182 osg::ref_ptr<osg::Geometry> WMVectorPlot::buildPlotSlices()
183 {
184  std::shared_ptr< WProgress > progress( new WProgress( "Vector Plot", 4 ) );
185  m_progress->addSubProgress( progress );
186 
187  WPosition current = WKernel::getRunningKernel()->getSelectionManager()->getCrosshair()->getPosition();
188 
189  std::shared_ptr< WGridRegular3D > grid = std::dynamic_pointer_cast< WGridRegular3D >( m_dataSet->getGrid() );
190  std::shared_ptr< WValueSet< ValueType > > vals = std::dynamic_pointer_cast< WValueSet< ValueType > >( m_dataSet->getValueSet() );
191 
192  int maxX = grid->getNbCoordsX() - 1;
193  int maxY = grid->getNbCoordsY() - 1;
194  int maxZ = grid->getNbCoordsZ() - 1;
195  int nbX = maxX + 1;
196  int nbY = maxY + 1;
197  int nbZ = maxZ + 1;
198 
199  m_xSlice->setMax( grid->getNbCoordsX() - 1 );
200  m_ySlice->setMax( grid->getNbCoordsY() - 1 );
201  m_zSlice->setMax( grid->getNbCoordsZ() - 1 );
202 
203  WPosition texPos = grid->worldCoordToTexCoord( current );
204  double xSlice = texPos[0] * grid->getNbCoordsX() - 0.5;
205  double ySlice = texPos[1] * grid->getNbCoordsY() - 0.5;
206  double zSlice = texPos[2] * grid->getNbCoordsZ() - 0.5;
207 
208  m_xSlice->set( xSlice );
209  m_ySlice->set( ySlice );
210  m_zSlice->set( zSlice );
211 
212  // When working with the OpenSceneGraph, always use ref_ptr to store pointers to OSG objects. This allows OpenSceneGraph to manage
213  // its resources automatically.
214 
215  using osg::ref_ptr;
216  ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
217  ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
218  ref_ptr< osg::Geometry > geometry = ref_ptr< osg::Geometry >( new osg::Geometry );
219 
220  WColor color = m_aColor->get( true );
221 
222  float scaling = m_scale->get( true );
223 
224  if( ( ( *m_dataSet ).getValueSet()->order() == 1 ) && ( ( *m_dataSet ).getValueSet()->dimension() == 3 ) )
225  {
226  if( m_showOnAxial->get( true ) )
227  {
228  for( int x = 0; x < nbX; ++x )
229  {
230  for( int y = 0; y < nbY; ++y )
231  {
232  float vecCompX = vals->getScalar( ( x + y * nbX + static_cast< int >( zSlice ) * nbX * nbY ) * 3 ) / 2. * scaling;
233  float vecCompY = vals->getScalar( ( x + y * nbX + static_cast< int >( zSlice ) * nbX * nbY ) * 3 + 1 ) / 2. * scaling;
234  float vecCompZ = vals->getScalar( ( x + y * nbX + static_cast< int >( zSlice ) * nbX * nbY ) * 3 + 2 ) / 2. * scaling;
235 
236  if( !m_projectOnSlice->get( true ) )
237  {
238  vertices->push_back( osg::Vec3( x - vecCompX, y - vecCompY, zSlice - vecCompZ ) );
239  vertices->push_back( osg::Vec3( x + vecCompX, y + vecCompY, zSlice + vecCompZ ) );
240  if( m_coloringMode->get( true ) )
241  {
242  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
243  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
244  }
245  else
246  {
247  colors->push_back( color );
248  colors->push_back( color );
249  }
250  }
251  else
252  {
253  vertices->push_back( osg::Vec3( x - vecCompX, y - vecCompY, zSlice - 0.01f ) );
254  vertices->push_back( osg::Vec3( x + vecCompX, y + vecCompY, zSlice - 0.01f ) );
255  vertices->push_back( osg::Vec3( x - vecCompX, y - vecCompY, zSlice + 0.01f ) );
256  vertices->push_back( osg::Vec3( x + vecCompX, y + vecCompY, zSlice + 0.01f ) );
257  if( m_coloringMode->get( true ) )
258  {
259  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
260  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
261  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
262  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
263  }
264  else
265  {
266  colors->push_back( color );
267  colors->push_back( color );
268  colors->push_back( color );
269  colors->push_back( color );
270  }
271  }
272  }
273  }
274  }
275 
276  ++*progress;
277 
278  if( m_showOnCoronal->get( true ) )
279  {
280  for( int x = 0; x < nbX; ++x )
281  {
282  for( int z = 0; z < nbZ; ++z )
283  {
284  float vecCompX = vals->getScalar( ( x + static_cast< int >( ySlice ) * nbX + z * nbX * nbY ) * 3 ) / 2. * scaling;
285  float vecCompY = vals->getScalar( ( x + static_cast< int >( ySlice ) * nbX + z * nbX * nbY ) * 3 + 1 ) / 2. * scaling;
286  float vecCompZ = vals->getScalar( ( x + static_cast< int >( ySlice ) * nbX + z * nbX * nbY ) * 3 + 2 ) / 2. * scaling;
287 
288  if( !m_projectOnSlice->get( true ) )
289  {
290  vertices->push_back( osg::Vec3( x - vecCompX, ySlice - vecCompY, z - vecCompZ ) );
291  vertices->push_back( osg::Vec3( x + vecCompX, ySlice + vecCompY, z + vecCompZ ) );
292  if( m_coloringMode->get( true ) )
293  {
294  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
295  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
296  }
297  else
298  {
299  colors->push_back( color );
300  colors->push_back( color );
301  }
302  }
303  else
304  {
305  vertices->push_back( osg::Vec3( x - vecCompX, ySlice - 0.01f, z - vecCompZ ) );
306  vertices->push_back( osg::Vec3( x + vecCompX, ySlice - 0.01f, z + vecCompZ ) );
307  vertices->push_back( osg::Vec3( x - vecCompX, ySlice + 0.01f, z - vecCompZ ) );
308  vertices->push_back( osg::Vec3( x + vecCompX, ySlice + 0.01f, z + vecCompZ ) );
309  if( m_coloringMode->get( true ) )
310  {
311  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
312  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
313  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
314  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
315  }
316  else
317  {
318  colors->push_back( color );
319  colors->push_back( color );
320  colors->push_back( color );
321  colors->push_back( color );
322  }
323  }
324  }
325  }
326  }
327 
328  ++*progress;
329 
330  if( m_showOnSagittal->get( true ) )
331  {
332  for( int y = 0; y < nbY; ++y )
333  {
334  for( int z = 0; z < nbZ; ++z )
335  {
336  float vecCompX = vals->getScalar( ( static_cast< int >( xSlice ) + y * nbX + z * nbX * nbY ) * 3 ) / 2. * scaling;
337  float vecCompY = vals->getScalar( ( static_cast< int >( xSlice ) + y * nbX + z * nbX * nbY ) * 3 + 1 ) / 2. * scaling;
338  float vecCompZ = vals->getScalar( ( static_cast< int >( xSlice ) + y * nbX + z * nbX * nbY ) * 3 + 2 ) / 2. * scaling;
339 
340  if( !m_projectOnSlice->get( true ) )
341  {
342  vertices->push_back( osg::Vec3( xSlice + vecCompX, y + vecCompY, z + vecCompZ ) );
343  vertices->push_back( osg::Vec3( xSlice - vecCompX, y - vecCompY, z - vecCompZ ) );
344  if( m_coloringMode->get( true ) )
345  {
346  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
347  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
348  }
349  else
350  {
351  colors->push_back( color );
352  colors->push_back( color );
353  }
354  }
355  else
356  {
357  vertices->push_back( osg::Vec3( xSlice - 0.01f, y + vecCompY, z + vecCompZ ) );
358  vertices->push_back( osg::Vec3( xSlice - 0.01f, y - vecCompY, z - vecCompZ ) );
359  vertices->push_back( osg::Vec3( xSlice + 0.01f, y + vecCompY, z + vecCompZ ) );
360  vertices->push_back( osg::Vec3( xSlice + 0.01f, y - vecCompY, z - vecCompZ ) );
361  if( m_coloringMode->get( true ) )
362  {
363  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
364  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
365  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
366  colors->push_back( osg::Vec4( fabs( vecCompX ), fabs( vecCompY ), fabs( vecCompZ ), 1.0 ) );
367  }
368  else
369  {
370  colors->push_back( color );
371  colors->push_back( color );
372  colors->push_back( color );
373  colors->push_back( color );
374  }
375  }
376  }
377  }
378  }
379 
380  ++*progress;
381 
382  // Transform the vertices according to the matrix given in the grid.
383  transformVerts( vertices );
384 
385  for( size_t i = 0; i < vertices->size(); ++i )
386  {
387  osg::DrawElementsUInt* line = new osg::DrawElementsUInt( osg::PrimitiveSet::LINES, 0 );
388  line->push_back( i );
389  line->push_back( i + 1 );
390  ++i;
391  geometry->addPrimitiveSet( line );
392  }
393  }
394 
395  geometry->setVertexArray( vertices );
396  geometry->setColorArray( colors );
397  geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
398 
399  progress->finish();
400 
401  return geometry;
402 }
403 
404 
405 #endif // WMVECTORPLOT_H
std::shared_ptr< WSelectionManager > getSelectionManager()
get for selection manager
Definition: WKernel.cpp:214
static WKernel * getRunningKernel()
Returns pointer to the currently running kernel.
Definition: WKernel.cpp:117
Show an glyph plot (in this case the glyphs are arrows) of a vector data set.
Definition: WMVectorPlot.h:48
virtual void activate()
Callback for m_active.
virtual void connectors()
Initialize the connectors this module is using.
WPropBool m_showOnAxial
indicates whether the vector should be shown on axial slice
Definition: WMVectorPlot.h:169
void transformVerts(osg::ref_ptr< osg::Vec3Array > verts)
Transforms the given vertices according to m_matrix.
osg::ref_ptr< WGEShader > m_shader
the shader object for this module
Definition: WMVectorPlot.h:176
WPropBool m_coloringMode
indicates a set color or direction color coding.
Definition: WMVectorPlot.h:157
std::shared_ptr< WDataSetVector > m_dataSet
This is a pointer to the dataset the module is currently working on.
Definition: WMVectorPlot.h:148
WPropBool m_projectOnSlice
projects the vectors on the slice.
Definition: WMVectorPlot.h:155
WPropColor m_aColor
color
Definition: WMVectorPlot.h:172
WPropBool m_showOnSagittal
indicates whether the vector should be shown on sagittal slice
Definition: WMVectorPlot.h:165
void updateCallback()
The update callback that is called for the osg node of this module.
osg::ref_ptr< osg::Geode > m_rootNode
The root node used for this modules graphics.
Definition: WMVectorPlot.h:105
WPropDouble m_scale
Scaling of arrow length.
Definition: WMVectorPlot.h:174
WPropDouble m_xSlice
x position of the slice
Definition: WMVectorPlot.h:159
virtual void moduleMain()
Entry point after loading the module.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
WPropBool m_showOnCoronal
indicates whether the vector should be shown on coronal slice
Definition: WMVectorPlot.h:167
virtual void properties()
Initialize the properties for this module.
osg::ref_ptr< osg::Geometry > buildPlotSlices()
Creates a vector plot on the currently selected slices.
Definition: WMVectorPlot.h:182
virtual const std::string getDescription() const
Gives back a description of this module.
std::shared_ptr< WModuleInputData< WDataSetVector > > m_input
An input connector used to get datasets from other modules.
Definition: WMVectorPlot.h:143
virtual const std::string getName() const
Gives back the name of this module.
WPropDouble m_ySlice
y position of the slice
Definition: WMVectorPlot.h:161
std::shared_ptr< std::vector< WPosition > > m_positions
list of positions to plot vectors on, this will come from a selection tool class
Definition: WMVectorPlot.h:153
virtual ~WMVectorPlot()
Destructor.
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...
WMVectorPlot()
Default constructor.
WPosition m_oldPos
The previous position of the slides.
Definition: WMVectorPlot.h:178
WPropDouble m_zSlice
z position of the slice
Definition: WMVectorPlot.h:163
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
std::shared_ptr< WProgressCombiner > m_progress
Progress indicator used as parent for all progress' of this module.
Definition: WModule.h:652
This only is a 3d double vector.
Class managing progress inside of modules.
Definition: WProgress.h:42