Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkOdfVtkMapper2D.txx
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 
18 #ifndef __mitkOdfVtkMapper2D_txx__
19 #define __mitkOdfVtkMapper2D_txx__
20 
21 #include "mitkOdfVtkMapper2D.h"
22 #include "mitkDataNode.h"
23 #include "mitkBaseRenderer.h"
24 #include "mitkMatrixConvert.h"
25 #include "mitkGeometry3D.h"
26 #include "mitkTimeGeometry.h"
27 #include "mitkOdfNormalizationMethodProperty.h"
28 #include "mitkOdfScaleByProperty.h"
29 #include "mitkProperties.h"
30 #include "mitkTensorImage.h"
31 
32 #include "vtkSphereSource.h"
33 #include "vtkPropCollection.h"
34 #include "vtkMaskedGlyph3D.h"
35 #include "vtkGlyph2D.h"
36 #include "vtkGlyph3D.h"
37 #include "vtkMaskedProgrammableGlyphFilter.h"
38 #include "vtkImageData.h"
39 #include "vtkLinearTransform.h"
40 #include "vtkCamera.h"
41 #include "vtkPointData.h"
42 #include "vtkTransformPolyDataFilter.h"
43 #include "vtkTransform.h"
44 #include "vtkOdfSource.h"
45 #include "vtkDoubleArray.h"
46 #include "vtkLookupTable.h"
47 #include "vtkProperty.h"
48 #include "vtkPolyDataNormals.h"
49 #include "vtkLight.h"
50 #include "vtkLightCollection.h"
51 #include "vtkMath.h"
52 #include "vtkFloatArray.h"
53 #include "vtkDelaunay2D.h"
54 #include "vtkMapper.h"
55 #include <vtkInformationVector.h>
56 #include <vtkInformation.h>
57 #include "vtkRenderer.h"
58 
59 #include "itkOrientationDistributionFunction.h"
60 
61 #include "itkFixedArray.h"
62 
63 #include <mitkGL.h>
64 #include "vtkOpenGLRenderer.h"
65 
66 #define _USE_MATH_DEFINES
67 #include <math.h>
68 
69 #include <ciso646>
70 
71 
72 template<class T, int N>
73 vtkSmartPointer<vtkTransform> mitk::OdfVtkMapper2D<T,N>::m_OdfTransform = vtkSmartPointer<vtkTransform>::New();
74 
75 template<class T, int N>
76 vtkSmartPointer<vtkOdfSource> mitk::OdfVtkMapper2D<T,N>::m_OdfSource = vtkSmartPointer<vtkOdfSource>::New();
77 
78 template<class T, int N>
79 float mitk::OdfVtkMapper2D<T,N>::m_Scaling;
80 
81 template<class T, int N>
82 int mitk::OdfVtkMapper2D<T,N>::m_Normalization;
83 
84 template<class T, int N>
85 int mitk::OdfVtkMapper2D<T,N>::m_ScaleBy;
86 
87 template<class T, int N>
88 float mitk::OdfVtkMapper2D<T,N>::m_IndexParam1;
89 
90 template<class T, int N>
91 float mitk::OdfVtkMapper2D<T,N>::m_IndexParam2;
92 
93 template<class T, int N>
94 bool mitk::OdfVtkMapper2D<T, N>::m_toggleTensorEllipsoidView = false;
95 
96 template<class T, int N>
97 bool mitk::OdfVtkMapper2D<T, N>::m_toggleColourisationMode = false;
98 
99 template<class T, int N>
100 bool mitk::OdfVtkMapper2D<T, N>::m_toggleGlyphPlacementMode = true;
101 
102 template<class T, int N>
103 vtkSmartPointer<vtkDoubleArray> mitk::OdfVtkMapper2D<T, N>::m_colourScalars = nullptr;
104 
105 #define ODF_MAPPER_PI M_PI
106 
107 
108 template<class T, int N>
109 mitk::OdfVtkMapper2D<T,N>::LocalStorage::LocalStorage()
110 {
111  m_PropAssemblies.push_back(vtkPropAssembly::New());
112  m_PropAssemblies.push_back(vtkPropAssembly::New());
113  m_PropAssemblies.push_back(vtkPropAssembly::New());
114 
115  m_OdfsPlanes.push_back(vtkAppendPolyData::New());
116  m_OdfsPlanes.push_back(vtkAppendPolyData::New());
117  m_OdfsPlanes.push_back(vtkAppendPolyData::New());
118 
119  m_OdfsPlanes[0]->AddInputData(vtkPolyData::New());
120  m_OdfsPlanes[1]->AddInputData(vtkPolyData::New());
121  m_OdfsPlanes[2]->AddInputData(vtkPolyData::New());
122 
123  m_OdfsActors.push_back(vtkActor::New());
124  m_OdfsActors.push_back(vtkActor::New());
125  m_OdfsActors.push_back(vtkActor::New());
126 
127  m_OdfsActors[0]->GetProperty()->SetInterpolationToGouraud();
128  m_OdfsActors[1]->GetProperty()->SetInterpolationToGouraud();
129  m_OdfsActors[2]->GetProperty()->SetInterpolationToGouraud();
130 
131  m_OdfsMappers.push_back(vtkPolyDataMapper::New());
132  m_OdfsMappers.push_back(vtkPolyDataMapper::New());
133  m_OdfsMappers.push_back(vtkPolyDataMapper::New());
134 
135  vtkLookupTable *lut = vtkLookupTable::New();
136 
137  m_OdfsMappers[0]->SetLookupTable(lut);
138  m_OdfsMappers[1]->SetLookupTable(lut);
139  m_OdfsMappers[2]->SetLookupTable(lut);
140 
141  m_OdfsActors[0]->SetMapper(m_OdfsMappers[0]);
142  m_OdfsActors[1]->SetMapper(m_OdfsMappers[1]);
143  m_OdfsActors[2]->SetMapper(m_OdfsMappers[2]);
144 }
145 
146 template<class T, int N>
147 mitk::OdfVtkMapper2D<T,N>
148 ::OdfVtkMapper2D()
149 {
150 
151  m_Planes.push_back(vtkPlane::New());
152  m_Planes.push_back(vtkPlane::New());
153  m_Planes.push_back(vtkPlane::New());
154 
155  m_Cutters.push_back(vtkCutter::New());
156  m_Cutters.push_back(vtkCutter::New());
157  m_Cutters.push_back(vtkCutter::New());
158 
159  m_Cutters[0]->SetCutFunction( m_Planes[0] );
160  m_Cutters[0]->GenerateValues( 1, 0, 1 );
161 
162  m_Cutters[1]->SetCutFunction( m_Planes[1] );
163  m_Cutters[1]->GenerateValues( 1, 0, 1 );
164 
165  m_Cutters[2]->SetCutFunction( m_Planes[2] );
166  m_Cutters[2]->GenerateValues( 1, 0, 1 );
167 
168  // Windowing the cutted planes in direction 1
169  m_ThickPlanes1.push_back(vtkThickPlane::New());
170  m_ThickPlanes1.push_back(vtkThickPlane::New());
171  m_ThickPlanes1.push_back(vtkThickPlane::New());
172 
173  m_Clippers1.push_back(vtkClipPolyData::New());
174  m_Clippers1.push_back(vtkClipPolyData::New());
175  m_Clippers1.push_back(vtkClipPolyData::New());
176 
177  m_Clippers1[0]->SetClipFunction( m_ThickPlanes1[0] );
178  m_Clippers1[1]->SetClipFunction( m_ThickPlanes1[1] );
179  m_Clippers1[2]->SetClipFunction( m_ThickPlanes1[2] );
180 
181  // Windowing the cutted planes in direction 2
182  m_ThickPlanes2.push_back(vtkThickPlane::New());
183  m_ThickPlanes2.push_back(vtkThickPlane::New());
184  m_ThickPlanes2.push_back(vtkThickPlane::New());
185 
186  m_Clippers2.push_back(vtkClipPolyData::New());
187  m_Clippers2.push_back(vtkClipPolyData::New());
188  m_Clippers2.push_back(vtkClipPolyData::New());
189 
190  m_Clippers2[0]->SetClipFunction( m_ThickPlanes2[0] );
191  m_Clippers2[1]->SetClipFunction( m_ThickPlanes2[1] );
192  m_Clippers2[2]->SetClipFunction( m_ThickPlanes2[2] );
193 
194  m_ShowMaxNumber = 500;
195 }
196 
197 template<class T, int N>
198 mitk::OdfVtkMapper2D<T,N>
199 ::~OdfVtkMapper2D()
200 {
201 
202 }
203 
204 template<class T, int N>
205 mitk::Image* mitk::OdfVtkMapper2D<T,N>
206 ::GetInput()
207 {
208  return static_cast<mitk::Image * > ( m_DataNode->GetData() );
209 }
210 
211 template<class T, int N>
212 vtkProp* mitk::OdfVtkMapper2D<T,N>
213 ::GetVtkProp(mitk::BaseRenderer* renderer)
214 {
215  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
216  return localStorage->m_PropAssemblies[GetIndex(renderer)];
217 }
218 
219 template<class T, int N>
220 int mitk::OdfVtkMapper2D<T,N>
221 ::GetIndex(mitk::BaseRenderer* renderer)
222 {
223  if(!strcmp(renderer->GetName(),"stdmulti.widget1"))
224  return 0;
225 
226  if(!strcmp(renderer->GetName(),"stdmulti.widget2"))
227  return 1;
228 
229  if(!strcmp(renderer->GetName(),"stdmulti.widget3"))
230  return 2;
231 
232  return 0;
233 }
234 
235 template<class T, int N>
236 void mitk::OdfVtkMapper2D<T,N>
237 ::GlyphMethod(void *arg)
238 {
239  vtkMaskedProgrammableGlyphFilter* pfilter=(vtkMaskedProgrammableGlyphFilter*)arg;
240 
241  double point[3];
242  double debugpoint[3];
243  pfilter->GetPoint(point);
244  pfilter->GetPoint(debugpoint);
245 
246  itk::Point<double,3> p(point);
247  Vector3D spacing = pfilter->GetGeometry()->GetSpacing();
248  p[0] /= spacing[0];
249  p[1] /= spacing[1];
250  p[2] /= spacing[2];
251 
252  mitk::Point3D p2;
253  pfilter->GetGeometry()->IndexToWorld( p, p2 );
254  point[0] = p2[0];
255  point[1] = p2[1];
256  point[2] = p2[2];
257 
258  vtkPointData* data = pfilter->GetPointData();
259  vtkDataArray* odfvals = data->GetArray("vector");
260  vtkIdType id = pfilter->GetPointId();
261  m_OdfTransform->Identity();
262  m_OdfTransform->Translate(point[0],point[1],point[2]);
263 
264  typedef itk::OrientationDistributionFunction<float,N> OdfType;
265  OdfType odf;
266 
267  if( odfvals->GetNumberOfComponents()==6 and not m_toggleTensorEllipsoidView )
268  {
269  float tensorelems[6] = {
270  (float)odfvals->GetComponent(id,0),
271  (float)odfvals->GetComponent(id,1),
272  (float)odfvals->GetComponent(id,2),
273  (float)odfvals->GetComponent(id,3),
274  (float)odfvals->GetComponent(id,4),
275  (float)odfvals->GetComponent(id,5),
276  };
277  itk::DiffusionTensor3D<float> tensor(tensorelems);
278  odf.InitFromTensor(tensor);
279 
280  if( (pfilter-> GetColorMode()) == 0 ) // m_ColourisationMode; VTK_COLOR_BY_INPUT=0, VTK_COLOR_BY_SOURCE=1.
281  { /// \brief Colourisation of glyph like in MitkWorkbench's dti visualisation, r,g,b,a=x,y,z,fa of main direction of diffusion.
282 // unsigned char rgba[4] = {0,0,0,0};
283  double rgba[4] = {0,0,0,0};
284  rgba[3] = fabs(tensor.GetFractionalAnisotropy()); //* 255); // fa = FractionalAnisotropy => Helligkeit = Value, and alpha.
285  typename itk::DiffusionTensor3D<T>::EigenValuesArrayType eigenValues;
286  typename itk::DiffusionTensor3D<T>::EigenVectorsMatrixType eigenVectors;
287  tensor.ComputeEigenAnalysis( eigenValues, eigenVectors ); // normalized eigenvectors as rows in ascending order.
288  rgba[0] = (fabs( eigenVectors(2, 0) ) * rgba[3]);
289  rgba[1] = (fabs( eigenVectors(2, 1) ) * rgba[3]);
290  rgba[2] = (fabs( eigenVectors(2, 2) ) * rgba[3]);
291 //#define __IMG_DAT_ITEM__CLIP_00_FF__(val) (val) = ( (val) < 0 ) ? ( 0 ) : ( ( (val) > 255 ) ? ( 255 ) : ( (val) ) );
292 #define __IMG_DAT_ITEM__CLIP_0_1__(val) (val) = ( (val) < 0.0 ) ? ( 0.0 ) : ( ( (val) > 1.0 ) ? ( 1.0 ) : ( (val) ) );
293  __IMG_DAT_ITEM__CLIP_0_1__(rgba[0]);
294  __IMG_DAT_ITEM__CLIP_0_1__(rgba[1]);
295  __IMG_DAT_ITEM__CLIP_0_1__(rgba[2]);
296  __IMG_DAT_ITEM__CLIP_0_1__(rgba[3]);
297  m_colourScalars-> InsertNextTuple4( rgba[0], rgba[1], rgba[2], rgba[3] ); // Allocates space automaticaly.
298 
299  data-> AddArray( m_colourScalars );
300  data-> SetActiveScalars( "GLYPH_COLORS" );
301  }
302  else
303  {
304  data-> SetActiveScalars( "vector" );
305  data-> RemoveArray( "GLYPH_COLORS" );
306  }
307  }
308 
309  else if( odfvals->GetNumberOfComponents()==6 and m_toggleTensorEllipsoidView )
310  {
311  float tensorElements[6] = {
312  (float)odfvals->GetComponent(id, 0), (float)odfvals->GetComponent(id, 1), (float)odfvals->GetComponent(id, 2),
313  (float)odfvals->GetComponent(id, 3), (float)odfvals->GetComponent(id, 4), (float)odfvals->GetComponent(id, 5),
314  };
315  itk::DiffusionTensor3D<float> tensor( tensorElements );
316  odf.InitFromEllipsoid( tensor );
317 
318  if( (pfilter-> GetColorMode()) == 0 ) // m_ColourisationMode; VTK_COLOR_BY_INPUT=0, VTK_COLOR_BY_SOURCE=1.
319  { /// \brief Colourisation of glyph like in MitkWorkbench's dti visualisation, r,g,b,a=x,y,z,fa of main direction of diffusion.
320  double rgba[4] = {0,0,0,0};
321  rgba[3] = fabs( tensor.GetFractionalAnisotropy()); // * 255 ); // fa = FractionalAnisotropy => Helligkeit = Value
322  typename itk::DiffusionTensor3D<T>::EigenValuesArrayType eigenValues;
323  typename itk::DiffusionTensor3D<T>::EigenVectorsMatrixType eigenVectors;
324  tensor.ComputeEigenAnalysis( eigenValues, eigenVectors ); // normalized eigenvectors as rows in ascending order.
325  rgba[0] = (fabs( eigenVectors(2, 0) ) * rgba[3]);
326  rgba[1] = (fabs( eigenVectors(2, 1) ) * rgba[3]);
327  rgba[2] = (fabs( eigenVectors(2, 2) ) * rgba[3]);
328  __IMG_DAT_ITEM__CLIP_0_1__(rgba[0]);
329  __IMG_DAT_ITEM__CLIP_0_1__(rgba[1]);
330  __IMG_DAT_ITEM__CLIP_0_1__(rgba[2]);
331  __IMG_DAT_ITEM__CLIP_0_1__(rgba[3]);
332 
333  m_colourScalars-> InsertNextTuple4( rgba[0], rgba[1], rgba[2], rgba[3] );
334  data-> CopyScalarsOn();
335  data-> SetCopyAttribute(id, 1);
336  data-> SetCopyScalars(id);
337  data-> CopyAllOn();
338  data-> SetDebug('1');
339 
340  pfilter-> DebugOn();
341  pfilter-> GetOutput()-> DebugOn();
342  pfilter-> GetOutput()-> GetPointData()-> CopyScalarsOn();
343 
344  data-> AddArray( m_colourScalars );
345  data-> SetActiveScalars( "GLYPH_COLORS" );
346 
347 #ifndef NDEBUG
348  {
349  vtkIndent indent;
350  std::cout << "<data>\n";
351  data-> PrintSelf(std::cout, indent.GetNextIndent());
352  std::cout << "</data>\n<pfilter>\n";
353  pfilter-> PrintSelf(std::cout, indent.GetNextIndent());
354  std::cout << pfilter->GetOutput()->GetClassName() << "\n";
355  pfilter-> GetOutput()-> PrintSelf(std::cout, indent.GetNextIndent());
356  pfilter-> GetOutput()->GetPointData()-> PrintSelf(std::cout, indent.GetNextIndent());
357  pfilter-> GetOutput()->GetPointData()->GetScalars()-> PrintSelf(std::cout, indent.GetNextIndent());
358  std::cout << "</pfilter>";
359  }
360 #endif
361 
362  }
363  else
364  {
365  data-> SetActiveScalars( "vector" );
366  data-> RemoveArray( "GLYPH_COLORS" );
367  }
368  }
369 
370  else
371  {
372  for(int i=0; i<N; i++)
373  odf[i] = (double)odfvals->GetComponent(id,i);
374  }
375 
376  switch(m_ScaleBy)
377  {
378  case ODFSB_NONE:
379  m_OdfSource->SetScale(m_Scaling);
380  break;
381  case ODFSB_GFA:
382  m_OdfSource->SetScale(m_Scaling*odf.GetGeneralizedGFA(m_IndexParam1, m_IndexParam2));
383  break;
384  case ODFSB_PC:
385  m_OdfSource->SetScale(m_Scaling*odf.GetPrincipleCurvature(m_IndexParam1, m_IndexParam2, 0));
386  break;
387  }
388 
389  m_OdfSource->SetNormalization(m_Normalization);
390  m_OdfSource->SetOdf(odf);
391  m_OdfSource->Modified();
392 }
393 
394 template<class T, int N>
395 typename mitk::OdfVtkMapper2D<T,N>::OdfDisplayGeometry mitk::OdfVtkMapper2D<T,N>
396 ::MeasureDisplayedGeometry(mitk::BaseRenderer* renderer)
397 {
398  PlaneGeometry::ConstPointer worldPlaneGeometry = renderer->GetCurrentWorldPlaneGeometry();
399 
400  // set up the cutter orientation according to the current geometry of
401  // the renderers plane
402  double vp[ 3 ], vnormal[ 3 ];
403  Point3D point = worldPlaneGeometry->GetOrigin();
404  Vector3D normal = worldPlaneGeometry->GetNormal(); normal.Normalize();
405  vnl2vtk( point.GetVnlVector(), vp );
406  vnl2vtk( normal.GetVnlVector(), vnormal );
407 
408  Point2D dispSizeInMM = renderer->GetViewportSizeInMM();
409 
410  Point2D displayGeometryOriginInMM = renderer->GetOriginInMM();
411 
412  mitk::Vector2D size = dispSizeInMM.GetVectorFromOrigin();
413  mitk::Vector2D origin = displayGeometryOriginInMM.GetVectorFromOrigin();
414 
415  //
416  // |------O------|
417  // | d2 |
418  // L d1 M |
419  // | |
420  // |-------------|
421  //
422 
423  mitk::Vector2D M;
424  mitk::Vector2D L;
425  mitk::Vector2D O;
426 
427  M[0] = origin[0] + size[0]/2;
428  M[1] = origin[1] + size[1]/2;
429 
430  L[0] = origin[0];
431  L[1] = origin[1] + size[1]/2;
432 
433  O[0] = origin[0] + size[0]/2;
434  O[1] = origin[1] + size[1];
435 
436  mitk::Point2D point1;
437  point1[0] = M[0]; point1[1] = M[1];
438  mitk::Point3D M3D;
439  renderer->GetCurrentWorldPlaneGeometry()->Map(point1, M3D);
440 
441  point1[0] = L[0]; point1[1] = L[1];
442  mitk::Point3D L3D;
443  renderer->GetCurrentWorldPlaneGeometry()->Map(point1, L3D);
444 
445  point1[0] = O[0]; point1[1] = O[1];
446  mitk::Point3D O3D;
447  renderer->GetCurrentWorldPlaneGeometry()->Map(point1, O3D);
448 
449  double d1 = sqrt((M3D[0]-L3D[0])*(M3D[0]-L3D[0])
450  + (M3D[1]-L3D[1])*(M3D[1]-L3D[1])
451  + (M3D[2]-L3D[2])*(M3D[2]-L3D[2]));
452  double d2 = sqrt((M3D[0]-O3D[0])*(M3D[0]-O3D[0])
453  + (M3D[1]-O3D[1])*(M3D[1]-O3D[1])
454  + (M3D[2]-O3D[2])*(M3D[2]-O3D[2]));
455  double d = d1>d2 ? d1 : d2;
456  d = d2;
457 
458  OdfDisplayGeometry retval;
459  retval.vp[0] = vp[0];
460  retval.vp[1] = vp[1];
461  retval.vp[2] = vp[2];
462  retval.vnormal[0] = vnormal[0];
463  retval.vnormal[1] = vnormal[1];
464  retval.vnormal[2] = vnormal[2];
465  retval.normal[0] = normal[0];
466  retval.normal[1] = normal[1];
467  retval.normal[2] = normal[2];
468  retval.d = d;
469  retval.d1 = d1;
470  retval.d2 = d2;
471  retval.M3D[0] = M3D[0];
472  retval.M3D[1] = M3D[1];
473  retval.M3D[2] = M3D[2];
474  retval.L3D[0] = L3D[0];
475  retval.L3D[1] = L3D[1];
476  retval.L3D[2] = L3D[2];
477  retval.O3D[0] = O3D[0];
478  retval.O3D[1] = O3D[1];
479  retval.O3D[2] = O3D[2];
480 
481  retval.vp_original[0] = vp[0];
482  retval.vp_original[1] = vp[1];
483  retval.vp_original[2] = vp[2];
484  retval.vnormal_original[0] = vnormal[0];
485  retval.vnormal_original[1] = vnormal[1];
486  retval.vnormal_original[2] = vnormal[2];
487  retval.size[0] = size[0];
488  retval.size[1] = size[1];
489  retval.origin[0] = origin[0];
490  retval.origin[1] = origin[1];
491 
492  return retval;
493 }
494 
495 template<class T, int N>
496 void mitk::OdfVtkMapper2D<T,N>
497 ::Slice(mitk::BaseRenderer* renderer, OdfDisplayGeometry dispGeo)
498 {
499  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
500 
501  vtkLinearTransform * vtktransform =
502  this->GetDataNode()->GetVtkTransform(this->GetTimestep());
503 
504  int index = GetIndex(renderer);
505 
506  vtkSmartPointer<vtkTransform> inversetransform = vtkSmartPointer<vtkTransform>::New();
507  inversetransform->Identity();
508  inversetransform->Concatenate(vtktransform->GetLinearInverse());
509  double myscale[3];
510  ((vtkTransform*)vtktransform)->GetScale(myscale);
511  inversetransform->PostMultiply();
512  inversetransform->Scale(1*myscale[0],1*myscale[1],1*myscale[2]);
513  inversetransform->TransformPoint( dispGeo.vp, dispGeo.vp );
514  inversetransform->TransformNormalAtPoint( dispGeo.vp, dispGeo.vnormal, dispGeo.vnormal );
515 
516  // vtk works in axis align coords
517  // thus the normal also must be axis align, since
518  // we do not allow arbitrary cutting through volume
519  //
520  // vnormal should already be axis align, but in order
521  // to get rid of precision effects, we set the two smaller
522  // components to zero here
523  int dims[3];
524  m_VtkImage->GetDimensions(dims);
525  double spac[3];
526  m_VtkImage->GetSpacing(spac);
527  if(fabs(dispGeo.vnormal[0]) > fabs(dispGeo.vnormal[1])
528  && fabs(dispGeo.vnormal[0]) > fabs(dispGeo.vnormal[2]) )
529  {
530  if(fabs(dispGeo.vp[0]/spac[0]) < 0.4)
531  dispGeo.vp[0] = 0.4*spac[0];
532  if(fabs(dispGeo.vp[0]/spac[0]) > (dims[0]-1)-0.4)
533  dispGeo.vp[0] = ((dims[0]-1)-0.4)*spac[0];
534  dispGeo.vnormal[1] = 0;
535  dispGeo.vnormal[2] = 0;
536  }
537 
538  if(fabs(dispGeo.vnormal[1]) > fabs(dispGeo.vnormal[0]) && fabs(dispGeo.vnormal[1]) > fabs(dispGeo.vnormal[2]) )
539  {
540  if(fabs(dispGeo.vp[1]/spac[1]) < 0.4)
541  dispGeo.vp[1] = 0.4*spac[1];
542  if(fabs(dispGeo.vp[1]/spac[1]) > (dims[1]-1)-0.4)
543  dispGeo.vp[1] = ((dims[1]-1)-0.4)*spac[1];
544  dispGeo.vnormal[0] = 0;
545  dispGeo.vnormal[2] = 0;
546  }
547 
548  if(fabs(dispGeo.vnormal[2]) > fabs(dispGeo.vnormal[1]) && fabs(dispGeo.vnormal[2]) > fabs(dispGeo.vnormal[0]) )
549  {
550  if(fabs(dispGeo.vp[2]/spac[2]) < 0.4)
551  dispGeo.vp[2] = 0.4*spac[2];
552  if(fabs(dispGeo.vp[2]/spac[2]) > (dims[2]-1)-0.4)
553  dispGeo.vp[2] = ((dims[2]-1)-0.4)*spac[2];
554  dispGeo.vnormal[0] = 0;
555  dispGeo.vnormal[1] = 0;
556  }
557 
558 
559  m_Planes[index]->SetTransform( (vtkAbstractTransform*)NULL );
560  m_Planes[index]->SetOrigin( dispGeo.vp );
561  m_Planes[index]->SetNormal( dispGeo.vnormal );
562 
563  vtkSmartPointer<vtkPoints> points;
564  vtkSmartPointer<vtkPoints> tmppoints;
565  vtkSmartPointer<vtkPolyData> polydata;
566  vtkSmartPointer<vtkFloatArray> pointdata;
567  vtkSmartPointer<vtkDelaunay2D> delaunay;
568  vtkSmartPointer<vtkPolyData> cuttedPlane;
569 
570  // the cutter only works if we do not have a 2D-image
571  // or if we have a 2D-image and want to see the whole image.
572  //
573  // for side views of 2D-images, we need some special treatment
574  if(!( (dims[0] == 1 && dispGeo.vnormal[0] != 0) ||
575  (dims[1] == 1 && dispGeo.vnormal[1] != 0) ||
576  (dims[2] == 1 && dispGeo.vnormal[2] != 0) ))
577  {
578  m_Cutters[index]->SetCutFunction( m_Planes[index] );
579  m_Cutters[index]->SetInputData( m_VtkImage );
580  m_Cutters[index]->Update();
581  cuttedPlane = m_Cutters[index]->GetOutput();
582  }
583  else
584  {
585  // cutting of a 2D-Volume does not work,
586  // so we have to build up our own polydata object
587  cuttedPlane = vtkPolyData::New();
588  points = vtkPoints::New();
589  points->SetNumberOfPoints(m_VtkImage->GetNumberOfPoints());
590  for(int i=0; i<m_VtkImage->GetNumberOfPoints(); i++)
591  {
592  points->SetPoint(i, m_VtkImage->GetPoint(i));
593  }
594  cuttedPlane->SetPoints(points);
595 
596  pointdata = vtkFloatArray::New();
597  int comps = m_VtkImage->GetPointData()->GetScalars()->GetNumberOfComponents();
598  pointdata->SetNumberOfComponents(comps);
599  int tuples = m_VtkImage->GetPointData()->GetScalars()->GetNumberOfTuples();
600  pointdata->SetNumberOfTuples(tuples);
601  for(int i=0; i<tuples; i++)
602  {
603  pointdata->SetTuple( i, m_VtkImage->GetPointData()->GetScalars()->GetTuple(i) );
604  }
605  pointdata->SetName( "vector" );
606  cuttedPlane->GetPointData()->AddArray(pointdata);
607 
608  int nZero1, nZero2;
609  if(dims[0]==1)
610  {
611  nZero1 = 1; nZero2 = 2;
612  }
613  else if(dims[1]==1)
614  {
615  nZero1 = 0; nZero2 = 2;
616  }
617  else
618  {
619  nZero1 = 0; nZero2 = 1;
620  }
621 
622  tmppoints = vtkPoints::New();
623  for(int j=0; j<m_VtkImage->GetNumberOfPoints(); j++){
624  double pt[3];
625  m_VtkImage->GetPoint(j,pt);
626  tmppoints->InsertNextPoint(pt[nZero1],pt[nZero2],0);
627  }
628 
629  polydata = vtkPolyData::New();
630  polydata->SetPoints( tmppoints );
631  delaunay = vtkDelaunay2D::New();
632  delaunay->SetInputData( polydata );
633  delaunay->Update();
634  vtkCellArray* polys = delaunay->GetOutput()->GetPolys();
635  cuttedPlane->SetPolys(polys);
636  }
637 
638  if(cuttedPlane->GetNumberOfPoints())
639  {
640  // WINDOWING HERE
641  inversetransform = vtkTransform::New();
642  inversetransform->Identity();
643  inversetransform->Concatenate(vtktransform->GetLinearInverse());
644  double myscale[3];
645  ((vtkTransform*)vtktransform)->GetScale(myscale);
646  inversetransform->PostMultiply();
647  inversetransform->Scale(1*myscale[0],1*myscale[1],1*myscale[2]);
648 
649  dispGeo.vnormal[0] = dispGeo.M3D[0]-dispGeo.O3D[0];
650  dispGeo.vnormal[1] = dispGeo.M3D[1]-dispGeo.O3D[1];
651  dispGeo.vnormal[2] = dispGeo.M3D[2]-dispGeo.O3D[2];
652  vtkMath::Normalize(dispGeo.vnormal);
653  dispGeo.vp[0] = dispGeo.M3D[0];
654  dispGeo.vp[1] = dispGeo.M3D[1];
655  dispGeo.vp[2] = dispGeo.M3D[2];
656 
657  inversetransform->TransformPoint( dispGeo.vp, dispGeo.vp );
658  inversetransform->TransformNormalAtPoint( dispGeo.vp, dispGeo.vnormal, dispGeo.vnormal );
659 
660  m_ThickPlanes1[index]->count = 0;
661  m_ThickPlanes1[index]->SetTransform((vtkAbstractTransform*)NULL );
662  m_ThickPlanes1[index]->SetPose( dispGeo.vnormal, dispGeo.vp );
663  m_ThickPlanes1[index]->SetThickness(dispGeo.d2);
664  m_Clippers1[index]->SetClipFunction( m_ThickPlanes1[index] );
665  m_Clippers1[index]->SetInputData( cuttedPlane );
666  m_Clippers1[index]->SetInsideOut(1);
667  m_Clippers1[index]->Update();
668 
669  dispGeo.vnormal[0] = dispGeo.M3D[0]-dispGeo.L3D[0];
670  dispGeo.vnormal[1] = dispGeo.M3D[1]-dispGeo.L3D[1];
671  dispGeo.vnormal[2] = dispGeo.M3D[2]-dispGeo.L3D[2];
672  vtkMath::Normalize(dispGeo.vnormal);
673  dispGeo.vp[0] = dispGeo.M3D[0];
674  dispGeo.vp[1] = dispGeo.M3D[1];
675  dispGeo.vp[2] = dispGeo.M3D[2];
676 
677  inversetransform->TransformPoint( dispGeo.vp, dispGeo.vp );
678  inversetransform->TransformNormalAtPoint( dispGeo.vp, dispGeo.vnormal, dispGeo.vnormal );
679 
680  m_ThickPlanes2[index]->count = 0;
681  m_ThickPlanes2[index]->SetTransform((vtkAbstractTransform*)NULL );
682  m_ThickPlanes2[index]->SetPose( dispGeo.vnormal, dispGeo.vp );
683  m_ThickPlanes2[index]->SetThickness(dispGeo.d1);
684  m_Clippers2[index]->SetClipFunction( m_ThickPlanes2[index] );
685  m_Clippers2[index]->SetInputData( m_Clippers1[index]->GetOutput() );
686  m_Clippers2[index]->SetInsideOut(1);
687  m_Clippers2[index]->Update();
688 
689  cuttedPlane = m_Clippers2[index]->GetOutput ();
690 
691  if(cuttedPlane->GetNumberOfPoints())
692  {
693  localStorage->m_OdfsPlanes[index]->RemoveAllInputs();
694 
695  vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New();
696  normals->SetInputConnection( m_OdfSource->GetOutputPort() );
697  normals->SplittingOff();
698  normals->ConsistencyOff();
699  normals->AutoOrientNormalsOff();
700  normals->ComputePointNormalsOn();
701  normals->ComputeCellNormalsOff();
702  normals->FlipNormalsOff();
703  normals->NonManifoldTraversalOff();
704 
705  vtkSmartPointer<vtkTransformPolyDataFilter> trans = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
706  trans->SetInputConnection( normals->GetOutputPort() );
707  trans->SetTransform(m_OdfTransform);
708 
709  vtkSmartPointer<vtkMaskedProgrammableGlyphFilter> glyphGenerator = vtkSmartPointer<vtkMaskedProgrammableGlyphFilter>::New();
710  glyphGenerator->SetMaximumNumberOfPoints(std::min(m_ShowMaxNumber,(int)cuttedPlane->GetNumberOfPoints()));
711 
712  glyphGenerator->SetRandomMode( m_toggleGlyphPlacementMode );
713 
714  glyphGenerator->SetUseMaskPoints(1);
715  glyphGenerator->SetSourceConnection(trans->GetOutputPort() );
716  glyphGenerator->SetInput(cuttedPlane);
717 
718  if( not m_toggleColourisationMode )
719  {
720  glyphGenerator-> SetColorModeToColorBySource();
721  glyphGenerator-> SetInputArrayToProcess(0,0,0, vtkDataObject::FIELD_ASSOCIATION_POINTS , "vector");
722  if(m_colourScalars != nullptr) { m_colourScalars-> Initialize(); }
723  }
724  else if ( m_toggleColourisationMode )
725  {
726  m_colourScalars = vtkSmartPointer<vtkDoubleArray>::New();
727  m_colourScalars-> SetNumberOfComponents( 4 ); // red, green, blue and alpha are the 4 components per tuple.
728  m_colourScalars-> SetName( "GLYPH_COLORS" );
729  glyphGenerator-> SetColorModeToColorByInput();
730  glyphGenerator-> SetInputArrayToProcess(0,0,0, vtkDataObject::FIELD_ASSOCIATION_POINTS , "GLYPH_COLORS");
731  }
732 
733  glyphGenerator->SetGeometry(this->GetDataNode()->GetData()->GetGeometry());
734  glyphGenerator->SetGlyphMethod(&(GlyphMethod),(void *)glyphGenerator);
735 
736  try
737  {
738  glyphGenerator->Update();
739  }
740  catch( itk::ExceptionObject& err )
741  {
742  std::cout << err << std::endl;
743  }
744 
745  localStorage->m_OdfsPlanes[index]->AddInputConnection(glyphGenerator->GetOutputPort());
746  localStorage->m_OdfsPlanes[index]->Update();
747  }
748  }
749  localStorage->m_PropAssemblies[index]->VisibilityOn();
750  if(localStorage->m_PropAssemblies[index]->GetParts()->IsItemPresent(localStorage->m_OdfsActors[index]))
751  {
752  localStorage->m_PropAssemblies[index]->RemovePart(localStorage->m_OdfsActors[index]);
753  }
754  localStorage->m_OdfsMappers[index]->SetInputData(localStorage->m_OdfsPlanes[index]->GetOutput());
755  localStorage->m_PropAssemblies[index]->AddPart(localStorage->m_OdfsActors[index]);
756 }
757 
758 template<class T, int N>
759 bool mitk::OdfVtkMapper2D<T,N>
760 ::IsVisibleOdfs(mitk::BaseRenderer* renderer)
761 {
762  mitk::Image::Pointer input = const_cast<mitk::Image*>(this->GetInput());
763  const TimeGeometry *inputTimeGeometry = input->GetTimeGeometry();
764  if(inputTimeGeometry==NULL || inputTimeGeometry->CountTimeSteps()==0 || !inputTimeGeometry->IsValidTimeStep(this->GetTimestep()))
765  return false;
766 
767  if(this->IsPlaneRotated(renderer))
768  return false;
769 
770  bool retval = false;
771  switch(GetIndex(renderer))
772  {
773  case 0:
774  GetDataNode()->GetVisibility(retval, renderer, "VisibleOdfs_T");
775  break;
776  case 1:
777  GetDataNode()->GetVisibility(retval, renderer, "VisibleOdfs_S");
778  break;
779  case 2:
780  GetDataNode()->GetVisibility(retval, renderer, "VisibleOdfs_C");
781  break;
782  }
783 
784  return retval;
785 }
786 
787 template<class T, int N>
788 void mitk::OdfVtkMapper2D<T,N>
789 ::MitkRenderOverlay(mitk::BaseRenderer* renderer)
790 {
791  if ( this->IsVisibleOdfs(renderer)==false )
792  return;
793 
794  if ( this->GetVtkProp(renderer)->GetVisibility() )
795  this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer());
796 }
797 
798 template<class T, int N>
799 void mitk::OdfVtkMapper2D<T,N>
800 ::MitkRenderOpaqueGeometry(mitk::BaseRenderer* renderer)
801 {
802  if ( this->IsVisibleOdfs( renderer )==false )
803  return;
804 
805  if ( this->GetVtkProp(renderer)->GetVisibility() )
806  {
807  // adapt cam pos
808  this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() );
809  }
810 }
811 
812 template<class T, int N>
813 void mitk::OdfVtkMapper2D<T,N>
814 ::MitkRenderTranslucentGeometry(mitk::BaseRenderer* renderer)
815 {
816  if ( this->IsVisibleOdfs(renderer)==false )
817  return;
818 
819  if ( this->GetVtkProp(renderer)->GetVisibility() )
820  this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer());
821 
822 }
823 
824 template<class T, int N>
825 void mitk::OdfVtkMapper2D<T,N>
826 ::Update(mitk::BaseRenderer* renderer)
827 {
828  bool visible = true;
829  GetDataNode()->GetVisibility(visible, renderer, "visible");
830 
831  if ( !visible ) return;
832 
833  mitk::Image::Pointer input = const_cast<mitk::Image*>( this->GetInput() );
834  if ( input.IsNull() ) return ;
835 
836  std::string classname("TensorImage");
837  if(classname.compare(input->GetNameOfClass())==0)
838  m_VtkImage = dynamic_cast<mitk::TensorImage*>( this->GetInput() )->GetNonRgbVtkImageData();
839 
840  std::string qclassname("QBallImage");
841  if(qclassname.compare(input->GetNameOfClass())==0)
842  m_VtkImage = dynamic_cast<mitk::QBallImage*>( this->GetInput() )->GetNonRgbVtkImageData();
843 
844  if( m_VtkImage )
845  {
846  // make sure, that we have point data with more than 1 component (as vectors)
847  vtkPointData* pointData = m_VtkImage->GetPointData();
848  if ( pointData == NULL )
849  {
850  itkWarningMacro( << "m_VtkImage->GetPointData() returns NULL!" );
851  return ;
852  }
853  if ( pointData->GetNumberOfArrays() == 0 )
854  {
855  itkWarningMacro( << "m_VtkImage->GetPointData()->GetNumberOfArrays() is 0!" );
856  return ;
857  }
858  else if ( pointData->GetArray(0)->GetNumberOfComponents() != N
859  && pointData->GetArray(0)->GetNumberOfComponents() != 6 /*for tensor visualization*/)
860  {
861  itkWarningMacro( << "number of components != number of directions in ODF!" );
862  return;
863  }
864  else if ( pointData->GetArrayName( 0 ) == NULL )
865  {
866  m_VtkImage->GetPointData()->GetArray(0)->SetName("vector");
867  }
868 
869  GenerateDataForRenderer(renderer);
870  }
871  else
872  {
873  itkWarningMacro( << "m_VtkImage is NULL!" );
874  return ;
875  }
876 }
877 
878 template<class T, int N>
879 void mitk::OdfVtkMapper2D<T,N>
880 ::GenerateDataForRenderer( mitk::BaseRenderer *renderer )
881 {
882  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
883 
884  OdfDisplayGeometry dispGeo = MeasureDisplayedGeometry( renderer);
885 
886 
887  if ( (localStorage->m_LastUpdateTime >= m_DataNode->GetMTime()) //was the node modified?
888  && (localStorage->m_LastUpdateTime >= m_DataNode->GetPropertyList()->GetMTime()) //was a property modified?
889  && (localStorage->m_LastUpdateTime >= m_DataNode->GetPropertyList(renderer)->GetMTime())
890  && dispGeo.Equals(m_LastDisplayGeometry))
891  {
892  return;
893  }
894 
895  localStorage->m_LastUpdateTime.Modified();
896 
897  if(!IsVisibleOdfs(renderer))
898  {
899  localStorage->m_OdfsActors[0]->VisibilityOff();
900  localStorage->m_OdfsActors[1]->VisibilityOff();
901  localStorage->m_OdfsActors[2]->VisibilityOff();
902  }
903  else
904  {
905  localStorage->m_OdfsActors[0]->VisibilityOn();
906  localStorage->m_OdfsActors[1]->VisibilityOn();
907  localStorage->m_OdfsActors[2]->VisibilityOn();
908 
909  m_OdfSource->SetAdditionalScale(GetMinImageSpacing(GetIndex(renderer)));
910  ApplyPropertySettings();
911 
912  for(unsigned iter=0; iter<3; ++iter)
913  {
914  if( m_toggleColourisationMode == true )
915  {
916  localStorage-> m_OdfsMappers[iter]-> SetColorModeToDirectScalars();
917  localStorage-> m_OdfsMappers[iter]-> SelectColorArray("GLYPH_COLORS");
918  localStorage-> m_OdfsMappers[iter]-> ScalarVisibilityOn();
919  localStorage-> m_OdfsMappers[iter]-> SetScalarMode(3); // 0=Default, 1=UsePointData, 2=UseCellData, _3=UsePointFieldData_
920  // 4=UseCellFieldData, 5=UseFieldData, rot oder weiss, manchmal schwarz danach ?... double [0;1] statt char [0;255] ?
921  }
922  else if ( m_toggleColourisationMode == false )
923  {
924  localStorage-> m_OdfsMappers[iter]-> SetColorModeToDefault();
925  localStorage-> m_OdfsMappers[iter]-> SelectColorArray("vector");
926  localStorage-> m_OdfsMappers[iter]-> ScalarVisibilityOn();
927  localStorage-> m_OdfsMappers[iter]-> SetScalarMode(0); // 0=Default
928  }
929  }
930 
931  Slice(renderer, dispGeo);
932  m_LastDisplayGeometry = dispGeo;
933  }
934 }
935 
936 template<class T, int N>
937 double mitk::OdfVtkMapper2D<T,N>::GetMinImageSpacing( int index )
938 {
939  // Spacing adapted scaling
940  double spacing[3];
941  m_VtkImage->GetSpacing(spacing);
942  double min = spacing[0];
943  if(index==0)
944  {
945  min = spacing[0];
946  min = min > spacing[1] ? spacing[1] : min;
947  }
948  if(index==1)
949  {
950  min = spacing[1];
951  min = min > spacing[2] ? spacing[2] : min;
952  }
953  if(index==2)
954  {
955  min = spacing[0];
956  min = min > spacing[2] ? spacing[2] : min;
957  }
958  return min;
959 }
960 
961 template<class T, int N>
962 void mitk::OdfVtkMapper2D<T,N>
963 ::ApplyPropertySettings()
964 {
965  this->GetDataNode()->GetFloatProperty( "Scaling", m_Scaling );
966  this->GetDataNode()->GetIntProperty( "ShowMaxNumber", m_ShowMaxNumber );
967 
968  OdfNormalizationMethodProperty* nmp = dynamic_cast<OdfNormalizationMethodProperty*>(this->GetDataNode()->GetProperty( "Normalization" ));
969  if(nmp)
970  m_Normalization = nmp->GetNormalization();
971 
972  OdfScaleByProperty* sbp = dynamic_cast<OdfScaleByProperty*>(this->GetDataNode()->GetProperty( "ScaleBy" ));
973  if(sbp)
974  m_ScaleBy = sbp->GetScaleBy();
975 
976  this->GetDataNode()->GetFloatProperty( "IndexParam1", m_IndexParam1);
977  this->GetDataNode()->GetFloatProperty( "IndexParam2", m_IndexParam2);
978 
979  this-> GetDataNode()-> GetBoolProperty( "DiffusionCore.Rendering.OdfVtkMapper.SwitchTensorView", m_toggleTensorEllipsoidView );
980  this-> GetDataNode()-> GetBoolProperty( "DiffusionCore.Rendering.OdfVtkMapper.ColourisationModeBit", m_toggleColourisationMode );
981  this-> GetDataNode()-> GetBoolProperty( "DiffusionCore.Rendering.OdfVtkMapper.RandomModeBit", m_toggleGlyphPlacementMode);
982 }
983 
984 template <class T, int N>
985 bool mitk::OdfVtkMapper2D<T,N>
986 ::IsPlaneRotated(mitk::BaseRenderer* renderer)
987 {
988  PlaneGeometry::ConstPointer worldPlaneGeometry = renderer->GetCurrentWorldPlaneGeometry();
989 
990  double vnormal[ 3 ];
991  Vector3D normal = worldPlaneGeometry->GetNormal(); normal.Normalize();
992  vnl2vtk( normal.GetVnlVector(), vnormal );
993 
994  mitk::Image* currentImage = dynamic_cast<mitk::Image* >( this->GetDataNode()->GetData() );
995  if( currentImage == NULL )
996  return false;
997  mitk::Vector3D imageNormal0 = currentImage->GetSlicedGeometry()->GetAxisVector(0);
998  mitk::Vector3D imageNormal1 = currentImage->GetSlicedGeometry()->GetAxisVector(1);
999  mitk::Vector3D imageNormal2 = currentImage->GetSlicedGeometry()->GetAxisVector(2);
1000  imageNormal0.Normalize();
1001  imageNormal1.Normalize();
1002  imageNormal2.Normalize();
1003 
1004  double eps = 0.000001; // Did you mean: std::numeric_limits<T>::epsilon(); ?
1005  int test = 0;
1006  if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal0.GetVnlVector()))-1) > eps )
1007  test++;
1008  if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal1.GetVnlVector()))-1) > eps )
1009  test++;
1010  if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal2.GetVnlVector()))-1) > eps )
1011  test++;
1012  if (test==3)
1013  return true;
1014  return false;
1015 }
1016 
1017 template<class T, int N>
1018 void mitk::OdfVtkMapper2D<T,N>
1019 ::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* /*renderer*/, bool /*overwrite*/)
1020 {
1021  node->SetProperty( "ShowMaxNumber", mitk::IntProperty::New( 150 ) );
1022  node->SetProperty( "Scaling", mitk::FloatProperty::New( 1.0 ) );
1023  node->SetProperty( "Normalization", mitk::OdfNormalizationMethodProperty::New());
1024  node->SetProperty( "ScaleBy", mitk::OdfScaleByProperty::New());
1025  node->SetProperty( "IndexParam1", mitk::FloatProperty::New(2));
1026  node->SetProperty( "IndexParam2", mitk::FloatProperty::New(1));
1027  node->SetProperty( "visible", mitk::BoolProperty::New( true ) );
1028  node->SetProperty( "VisibleOdfs_T", mitk::BoolProperty::New( false ) );
1029  node->SetProperty( "VisibleOdfs_C", mitk::BoolProperty::New( false ) );
1030  node->SetProperty( "VisibleOdfs_S", mitk::BoolProperty::New( false ) );
1031  node->SetProperty( "layer", mitk::IntProperty::New(100));
1032  node->SetProperty( "DoRefresh", mitk::BoolProperty::New( true ) );
1033  node-> AddProperty( "DiffusionCore.Rendering.OdfVtkMapper.SwitchTensorView", mitk::BoolProperty::New( false) );
1034  node-> AddProperty( "DiffusionCore.Rendering.OdfVtkMapper.ColourisationModeBit", mitk::BoolProperty::New( false ) );
1035  node-> AddProperty( "DiffusionCore.Rendering.OdfVtkMapper.RandomModeBit", mitk::BoolProperty::New( true ) );
1036 }
1037 
1038 #endif // __mitkOdfVtkMapper2D_txx__
1039