Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkDoseImageVtkMapper2D.cpp
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 //MITK
19 #include <mitkDataNode.h>
20 #include <mitkDataNodeFactory.h>
21 #include <mitkImageSliceSelector.h>
26 #include <mitkPixelType.h>
27 #include <mitkPlaneGeometry.h>
28 #include <mitkProperties.h>
31 #include <mitkRTConstants.h>
35 #include "mitkPlaneClipping.h"
36 #include "mitkPropertyNameHelper.h"
37 
38 //MITK Rendering
40 
44 
45 //VTK
46 #include <vtkCamera.h>
47 #include <vtkCellData.h>
48 #include <vtkColorTransferFunction.h>
49 #include <vtkGeneralTransform.h>
50 #include <vtkImageChangeInformation.h>
51 #include <vtkImageData.h>
52 #include <vtkImageExtractComponents.h>
53 #include <vtkImageReslice.h>
54 #include <vtkLookupTable.h>
55 #include <vtkMatrix4x4.h>
56 #include <vtkPlaneSource.h>
57 #include <vtkPoints.h>
58 #include <vtkPolyDataMapper.h>
59 #include <vtkProperty.h>
60 #include <vtkTransform.h>
61 #include <vtkUnsignedCharArray.h>
62 
63 //ITK
64 #include <itkRGBAPixel.h>
65 
67 {
68 }
69 
71 {
72  //The 3D RW Mapper (PlaneGeometryDataVtkMapper3D) is listening to this event,
73  //in order to delete the images from the 3D RW.
74  this->InvokeEvent( itk::DeleteEvent() );
75 }
76 
77 //set the two points defining the textured plane according to the dimension and spacing
78 void mitk::DoseImageVtkMapper2D::GeneratePlane(mitk::BaseRenderer* renderer, double planeBounds[6])
79 {
80  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
81 
82  float depth = this->CalculateLayerDepth(renderer);
83  //Set the origin to (xMin; yMin; depth) of the plane. This is necessary for obtaining the correct
84  //plane size in crosshair rotation and swivel mode.
85  localStorage->m_Plane->SetOrigin(planeBounds[0], planeBounds[2], depth);
86  //These two points define the axes of the plane in combination with the origin.
87  //Point 1 is the x-axis and point 2 the y-axis.
88  //Each plane is transformed according to the view (axial, coronal and saggital) afterwards.
89  localStorage->m_Plane->SetPoint1(planeBounds[1] , planeBounds[2], depth); //P1: (xMax, yMin, depth)
90  localStorage->m_Plane->SetPoint2(planeBounds[0], planeBounds[3], depth); //P2: (xMin, yMax, depth)
91 }
92 
94 {
95  //get the clipping range to check how deep into z direction we can render images
96  double maxRange = renderer->GetVtkRenderer()->GetActiveCamera()->GetClippingRange()[1];
97 
98  //Due to a VTK bug, we cannot use the whole clipping range. /100 is empirically determined
99  float depth = -maxRange*0.01; // divide by 100
100  int layer = 0;
101  GetDataNode()->GetIntProperty( "layer", layer, renderer);
102  //add the layer property for each image to render images with a higher layer on top of the others
103  depth += layer*10; //*10: keep some room for each image (e.g. for QBalls in between)
104  if(depth > 0.0f) {
105  depth = 0.0f;
106  MITK_WARN << "Layer value exceeds clipping range. Set to minimum instead.";
107  }
108  return depth;
109 }
110 
112 {
113  return static_cast< const mitk::Image * >( GetDataNode()->GetData() );
114 }
115 
117 {
118  //return the actor corresponding to the renderer
119  return m_LSH.GetLocalStorage(renderer)->m_Actors;
120 }
121 
123 {
124 
125  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
126 
127  mitk::Image *input = const_cast< mitk::Image * >( this->GetInput() );
128  mitk::DataNode* datanode = this->GetDataNode();
129 
130  if ( input == NULL || input->IsInitialized() == false )
131  {
132  return;
133  }
134 
135  //check if there is a valid worldGeometry
136  const PlaneGeometry *worldGeometry = renderer->GetCurrentWorldPlaneGeometry();
137  if( ( worldGeometry == NULL ) || ( !worldGeometry->IsValid() ) || ( !worldGeometry->HasReferenceGeometry() ))
138  {
139  return;
140  }
141 
142  input->Update();
143 
144  // early out if there is no intersection of the current rendering geometry
145  // and the geometry of the image that is to be rendered.
146  if ( !RenderingGeometryIntersectsImage( worldGeometry, input->GetSlicedGeometry() ) )
147  {
148  // set image to NULL, to clear the texture in 3D, because
149  // the latest image is used there if the plane is out of the geometry
150  // see bug-13275
151  localStorage->m_ReslicedImage = NULL;
152  localStorage->m_Mapper->SetInputData( localStorage->m_EmptyPolyData );
153  return;
154  }
155 
156  //set main input for ExtractSliceFilter
157  localStorage->m_Reslicer->SetInput(input);
158  localStorage->m_Reslicer->SetWorldGeometry(worldGeometry);
159  localStorage->m_Reslicer->SetTimeStep( this->GetTimestep() );
160 
161  //set the transformation of the image to adapt reslice axis
162  localStorage->m_Reslicer->SetResliceTransformByGeometry( input->GetTimeGeometry()->GetGeometryForTimeStep( this->GetTimestep() ) );
163 
164  //is the geometry of the slice based on the input image or the worldgeometry?
165  bool inPlaneResampleExtentByGeometry = false;
166  datanode->GetBoolProperty("in plane resample extent by geometry", inPlaneResampleExtentByGeometry, renderer);
167  localStorage->m_Reslicer->SetInPlaneResampleExtentByGeometry(inPlaneResampleExtentByGeometry);
168 
169  // Initialize the interpolation mode for resampling; switch to nearest
170  // neighbor if the input image is too small.
171  if ( (input->GetDimension() >= 3) && (input->GetDimension(2) > 1) )
172  {
173  VtkResliceInterpolationProperty *resliceInterpolationProperty;
174  datanode->GetProperty(
175  resliceInterpolationProperty, "reslice interpolation" );
176 
177  int interpolationMode = VTK_RESLICE_NEAREST;
178  if ( resliceInterpolationProperty != NULL )
179  {
180  interpolationMode = resliceInterpolationProperty->GetInterpolation();
181  }
182 
183  switch ( interpolationMode )
184  {
185  case VTK_RESLICE_NEAREST:
186  localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_NEAREST);
187  break;
188  case VTK_RESLICE_LINEAR:
189  localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_LINEAR);
190  break;
191  case VTK_RESLICE_CUBIC:
192  localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_CUBIC);
193  break;
194  }
195  }
196  else
197  {
198  localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_NEAREST);
199  }
200 
201  //set the vtk output property to true, makes sure that no unneeded mitk image convertion
202  //is done.
203  localStorage->m_Reslicer->SetVtkOutputRequest(true);
204 
205  //Thickslicing
206  int thickSlicesMode = 0;
207  int thickSlicesNum = 1;
208  // Thick slices parameters
209  if( input->GetPixelType().GetNumberOfComponents() == 1 ) // for now only single component are allowed
210  {
212  if(dn)
213  {
214  ResliceMethodProperty *resliceMethodEnumProperty=0;
215 
216  if( dn->GetProperty( resliceMethodEnumProperty, "reslice.thickslices" ) && resliceMethodEnumProperty )
217  thickSlicesMode = resliceMethodEnumProperty->GetValueAsId();
218 
219  IntProperty *intProperty=0;
220  if( dn->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty )
221  {
222  thickSlicesNum = intProperty->GetValue();
223  if(thickSlicesNum < 1) thickSlicesNum=1;
224  if(thickSlicesNum > 10) thickSlicesNum=10;
225  }
226  }
227  else
228  {
229  MITK_WARN << "no associated widget plane data tree node found";
230  }
231  }
232 
233  const PlaneGeometry *planeGeometry = dynamic_cast< const PlaneGeometry * >( worldGeometry );
234 
235  if(thickSlicesMode > 0)
236  {
237  double dataZSpacing = 1.0;
238 
239  Vector3D normInIndex, normal;
240 
241  if ( planeGeometry != NULL ){
242  normal = planeGeometry->GetNormal();
243  }else{
244  const mitk::AbstractTransformGeometry* abstractGeometry = dynamic_cast< const AbstractTransformGeometry * >(worldGeometry);
245  if(abstractGeometry != NULL)
246  normal = abstractGeometry->GetPlane()->GetNormal();
247  else
248  return; //no fitting geometry set
249  }
250  normal.Normalize();
251 
252  input->GetTimeGeometry()->GetGeometryForTimeStep( this->GetTimestep() )->WorldToIndex( normal, normInIndex );
253 
254  dataZSpacing = 1.0 / normInIndex.GetNorm();
255 
256  localStorage->m_Reslicer->SetOutputDimensionality( 3 );
257  localStorage->m_Reslicer->SetOutputSpacingZDirection(dataZSpacing);
258  localStorage->m_Reslicer->SetOutputExtentZDirection( -thickSlicesNum, 0+thickSlicesNum );
259 
260  // Do the reslicing. Modified() is called to make sure that the reslicer is
261  // executed even though the input geometry information did not change; this
262  // is necessary when the input /em data, but not the /em geometry changes.
263  localStorage->m_TSFilter->SetThickSliceMode( thickSlicesMode-1 );
264  localStorage->m_TSFilter->SetInputData( localStorage->m_Reslicer->GetVtkOutput() );
265 
266  //vtkFilter=>mitkFilter=>vtkFilter update mechanism will fail without calling manually
267  localStorage->m_Reslicer->Modified();
268  localStorage->m_Reslicer->Update();
269 
270  localStorage->m_TSFilter->Modified();
271  localStorage->m_TSFilter->Update();
272  localStorage->m_ReslicedImage = localStorage->m_TSFilter->GetOutput();
273  }
274  else
275  {
276  //this is needed when thick mode was enable bevore. These variable have to be reset to default values
277  localStorage->m_Reslicer->SetOutputDimensionality( 2 );
278  localStorage->m_Reslicer->SetOutputSpacingZDirection(1.0);
279  localStorage->m_Reslicer->SetOutputExtentZDirection( 0, 0 );
280 
281 
282  localStorage->m_Reslicer->Modified();
283  //start the pipeline with updating the largest possible, needed if the geometry of the input has changed
284  localStorage->m_Reslicer->UpdateLargestPossibleRegion();
285  localStorage->m_ReslicedImage = localStorage->m_Reslicer->GetVtkOutput();
286  }
287 
288  // Bounds information for reslicing (only reuqired if reference geometry
289  // is present)
290  //this used for generating a vtkPLaneSource with the right size
291  double sliceBounds[6];
292  for ( int i = 0; i < 6; ++i )
293  {
294  sliceBounds[i] = 0.0;
295  }
296  localStorage->m_Reslicer->GetClippedPlaneBounds(sliceBounds);
297 
298  //get the spacing of the slice
299  localStorage->m_mmPerPixel = localStorage->m_Reslicer->GetOutputSpacing();
300 
301  // calculate minimum bounding rect of IMAGE in texture
302  {
303  double textureClippingBounds[6];
304  for ( int i = 0; i < 6; ++i )
305  {
306  textureClippingBounds[i] = 0.0;
307  }
308  // Calculate the actual bounds of the transformed plane clipped by the
309  // dataset bounding box; this is required for drawing the texture at the
310  // correct position during 3D mapping.
311  mitk::PlaneClipping::CalculateClippedPlaneBounds( input->GetGeometry(), planeGeometry, textureClippingBounds );
312 
313  textureClippingBounds[0] = static_cast< int >( textureClippingBounds[0] / localStorage->m_mmPerPixel[0] + 0.5 );
314  textureClippingBounds[1] = static_cast< int >( textureClippingBounds[1] / localStorage->m_mmPerPixel[0] + 0.5 );
315  textureClippingBounds[2] = static_cast< int >( textureClippingBounds[2] / localStorage->m_mmPerPixel[1] + 0.5 );
316  textureClippingBounds[3] = static_cast< int >( textureClippingBounds[3] / localStorage->m_mmPerPixel[1] + 0.5 );
317 
318  //clipping bounds for cutting the image
319  localStorage->m_LevelWindowFilter->SetClippingBounds(textureClippingBounds);
320  }
321 
322  //get the number of scalar components to distinguish between different image types
323  int numberOfComponents = localStorage->m_ReslicedImage->GetNumberOfScalarComponents();
324  //get the showIsoLines property
325  bool showIsoLines = false;
326  datanode->GetBoolProperty( "dose.showIsoLines", showIsoLines, renderer );
327 
328  if(showIsoLines) //contour rendering
329  {
330  //generate contours/outlines
331  localStorage->m_OutlinePolyData = CreateOutlinePolyData(renderer);
332 
333  float binaryOutlineWidth(1.0);
334  if ( datanode->GetFloatProperty( "outline width", binaryOutlineWidth, renderer ) )
335  {
336  if ( localStorage->m_Actors->GetNumberOfPaths() > 1 )
337  {
338  float binaryOutlineShadowWidth(1.5);
339  datanode->GetFloatProperty( "outline shadow width", binaryOutlineShadowWidth, renderer );
340 
341  dynamic_cast<vtkActor*>(localStorage->m_Actors->GetParts()->GetItemAsObject(0))
342  ->GetProperty()->SetLineWidth( binaryOutlineWidth * binaryOutlineShadowWidth );
343  }
344 
345  localStorage->m_Actor->GetProperty()->SetLineWidth( binaryOutlineWidth );
346  }
347  }
348  else
349  {
350  localStorage->m_ReslicedImage = NULL;
351  localStorage->m_Mapper->SetInputData( localStorage->m_EmptyPolyData );
352  return;
353  }
354 
355  this->ApplyOpacity( renderer );
356  this->ApplyRenderingMode(renderer);
357 
358  // do not use a VTK lookup table (we do that ourselves in m_LevelWindowFilter)
359  localStorage->m_Texture->MapColorScalarsThroughLookupTableOff();
360 
361  int displayedComponent = 0;
362 
363  if (datanode->GetIntProperty("Image.Displayed Component", displayedComponent, renderer) && numberOfComponents > 1)
364  {
365  localStorage->m_VectorComponentExtractor->SetComponents(displayedComponent);
366  localStorage->m_VectorComponentExtractor->SetInputData(localStorage->m_ReslicedImage);
367 
368  localStorage->m_LevelWindowFilter->SetInputConnection(localStorage->m_VectorComponentExtractor->GetOutputPort(0));
369  }
370  else
371  {
372  //connect the input with the levelwindow filter
373  localStorage->m_LevelWindowFilter->SetInputData(localStorage->m_ReslicedImage);
374  }
375 
376  // check for texture interpolation property
377  bool textureInterpolation = false;
378  GetDataNode()->GetBoolProperty( "texture interpolation", textureInterpolation, renderer );
379 
380  //set the interpolation modus according to the property
381  localStorage->m_Texture->SetInterpolate(textureInterpolation);
382 
383  // connect the texture with the output of the levelwindow filter
384  localStorage->m_Texture->SetInputConnection(localStorage->m_LevelWindowFilter->GetOutputPort());
385 
386  this->TransformActor( renderer );
387 
388  vtkActor* contourShadowActor = dynamic_cast<vtkActor*> (localStorage->m_Actors->GetParts()->GetItemAsObject(0));
389 
390  if(showIsoLines) //connect the mapper with the polyData which contains the lines
391  {
392  //We need the contour for the binary outline property as actor
393  localStorage->m_Mapper->SetInputData(localStorage->m_OutlinePolyData);
394  localStorage->m_Actor->SetTexture(NULL); //no texture for contours
395 
396  bool binaryOutlineShadow( false );
397  datanode->GetBoolProperty( "outline binary shadow", binaryOutlineShadow, renderer );
398 
399  if ( binaryOutlineShadow )
400  contourShadowActor->SetVisibility( true );
401  else
402  contourShadowActor->SetVisibility( false );
403  }
404  else
405  { //Connect the mapper with the input texture. This is the standard case.
406  //setup the textured plane
407  this->GeneratePlane( renderer, sliceBounds );
408  //set the plane as input for the mapper
409  localStorage->m_Mapper->SetInputConnection(localStorage->m_Plane->GetOutputPort());
410  //set the texture for the actor
411 
412  localStorage->m_Actor->SetTexture(localStorage->m_Texture);
413  contourShadowActor->SetVisibility( false );
414  }
415 
416  // We have been modified => save this for next Update()
417  localStorage->m_LastUpdateTime.Modified();
418 }
419 
421 {
422  LocalStorage *localStorage = this->GetLocalStorage( renderer );
423 
424  LevelWindow levelWindow;
425  this->GetDataNode()->GetLevelWindow( levelWindow, renderer, "levelwindow" );
426  localStorage->m_LevelWindowFilter->GetLookupTable()->SetRange( levelWindow.GetLowerWindowBound(), levelWindow.GetUpperWindowBound() );
427 
428  mitk::LevelWindow opacLevelWindow;
429  if( this->GetDataNode()->GetLevelWindow( opacLevelWindow, renderer, "opaclevelwindow" ) )
430  {
431  //pass the opaque level window to the filter
432  localStorage->m_LevelWindowFilter->SetMinOpacity(opacLevelWindow.GetLowerWindowBound());
433  localStorage->m_LevelWindowFilter->SetMaxOpacity(opacLevelWindow.GetUpperWindowBound());
434  }
435  else
436  {
437  //no opaque level window
438  localStorage->m_LevelWindowFilter->SetMinOpacity(0.0);
439  localStorage->m_LevelWindowFilter->SetMaxOpacity(255.0);
440  }
441 }
442 
444 {
445  LocalStorage *localStorage = this->GetLocalStorage( renderer );
446 
447  float rgb[3]= { 1.0f, 1.0f, 1.0f };
448 
449  // check for color prop and use it for rendering if it exists
450  // binary image hovering & binary image selection
451  bool hover = false;
452  bool selected = false;
453  GetDataNode()->GetBoolProperty("binaryimage.ishovering", hover, renderer);
454  GetDataNode()->GetBoolProperty("selected", selected, renderer);
455  if(hover && !selected)
456  {
457  mitk::ColorProperty::Pointer colorprop = dynamic_cast<mitk::ColorProperty*>(GetDataNode()->GetProperty
458  ("binaryimage.hoveringcolor", renderer));
459  if(colorprop.IsNotNull())
460  {
461  memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float));
462  }
463  else
464  {
465  GetDataNode()->GetColor( rgb, renderer, "color" );
466  }
467  }
468  if(selected)
469  {
470  mitk::ColorProperty::Pointer colorprop = dynamic_cast<mitk::ColorProperty*>(GetDataNode()->GetProperty
471  ("binaryimage.selectedcolor", renderer));
472  if(colorprop.IsNotNull()) {
473  memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float));
474  }
475  else
476  {
477  GetDataNode()->GetColor(rgb, renderer, "color");
478  }
479  }
480  if(!hover && !selected)
481  {
482  GetDataNode()->GetColor( rgb, renderer, "color" );
483  }
484 
485  double rgbConv[3] = {(double)rgb[0], (double)rgb[1], (double)rgb[2]}; //conversion to double for VTK
486  dynamic_cast<vtkActor*> (localStorage->m_Actors->GetParts()->GetItemAsObject(0))->GetProperty()->SetColor(rgbConv);
487  localStorage->m_Actor->GetProperty()->SetColor(rgbConv);
488 
489  if ( localStorage->m_Actors->GetParts()->GetNumberOfItems() > 1 )
490  {
491  float rgb[3]= { 1.0f, 1.0f, 1.0f };
492  mitk::ColorProperty::Pointer colorprop = dynamic_cast<mitk::ColorProperty*>(GetDataNode()->GetProperty
493  ("outline binary shadow color", renderer));
494  if(colorprop.IsNotNull())
495  {
496  memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float));
497  }
498  double rgbConv[3] = {(double)rgb[0], (double)rgb[1], (double)rgb[2]}; //conversion to double for VTK
499  dynamic_cast<vtkActor*>( localStorage->m_Actors->GetParts()->GetItemAsObject(0) )->GetProperty()->SetColor(rgbConv);
500  }
501 }
502 
504 {
505  LocalStorage* localStorage = this->GetLocalStorage( renderer );
506  float opacity = 1.0f;
507  // check for opacity prop and use it for rendering if it exists
508  GetDataNode()->GetOpacity( opacity, renderer, "opacity" );
509  //set the opacity according to the properties
510  localStorage->m_Actor->GetProperty()->SetOpacity(opacity);
511  if ( localStorage->m_Actors->GetParts()->GetNumberOfItems() > 1 )
512  {
513  dynamic_cast<vtkActor*>( localStorage->m_Actors->GetParts()->GetItemAsObject(0) )->GetProperty()->SetOpacity(opacity);
514  }
515 }
516 
518 {
519  LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer);
520 
521  bool binary = false;
522  this->GetDataNode()->GetBoolProperty( "binary", binary, renderer );
523  if(binary) // is it a binary image?
524  {
525  //for binary images, we always use our default LuT and map every value to (0,1)
526  //the opacity of 0 will always be 0.0. We never a apply a LuT/TfF nor a level window.
527  localStorage->m_LevelWindowFilter->SetLookupTable(localStorage->m_BinaryLookupTable);
528  }
529  else
530  {
531  //all other image types can make use of the rendering mode
533  mitk::RenderingModeProperty::Pointer mode = dynamic_cast<mitk::RenderingModeProperty*>(this->GetDataNode()->GetProperty( "Image Rendering.Mode", renderer ));
534  if(mode.IsNotNull())
535  {
536  renderingMode = mode->GetRenderingMode();
537  }
538  switch(renderingMode)
539  {
541  MITK_DEBUG << "'Image Rendering.Mode' = LevelWindow_LookupTable_Color";
542  this->ApplyLookuptable( renderer );
543  this->ApplyLevelWindow( renderer );
544  break;
546  MITK_DEBUG << "'Image Rendering.Mode' = LevelWindow_ColorTransferFunction_Color";
547  this->ApplyColorTransferFunction( renderer );
548  this->ApplyLevelWindow( renderer );
549  break;
551  MITK_DEBUG << "'Image Rendering.Mode' = LookupTable_Color";
552  this->ApplyLookuptable( renderer );
553  break;
555  MITK_DEBUG << "'Image Rendering.Mode' = ColorTransferFunction_Color";
556  this->ApplyColorTransferFunction( renderer );
557  break;
558  default:
559  MITK_ERROR << "No valid 'Image Rendering.Mode' set. Using LOOKUPTABLE_LEVELWINDOW_COLOR instead.";
560  this->ApplyLookuptable( renderer );
561  this->ApplyLevelWindow( renderer );
562  break;
563  }
564  }
565  //we apply color for all images (including binaries).
566  this->ApplyColor( renderer );
567 }
568 
570 {
571  LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer);
572  vtkLookupTable* usedLookupTable = localStorage->m_ColorLookupTable;
573 
574  // If lookup table or transferfunction use is requested...
575  mitk::LookupTableProperty::Pointer lookupTableProp = dynamic_cast<mitk::LookupTableProperty*>(this->GetDataNode()->GetProperty("LookupTable"));
576 
577  if( lookupTableProp.IsNotNull() ) // is a lookuptable set?
578  {
579  usedLookupTable = lookupTableProp->GetLookupTable()->GetVtkLookupTable();
580  }
581  else
582  {
583  //"Image Rendering.Mode was set to use a lookup table but there is no property 'LookupTable'.
584  //A default (rainbow) lookup table will be used.
585  //Here have to do nothing. Warning for the user has been removed, due to unwanted console output
586  //in every interation of the rendering.
587  }
588  localStorage->m_LevelWindowFilter->SetLookupTable(usedLookupTable);
589 }
590 
592 {
593  mitk::TransferFunctionProperty::Pointer transferFunctionProp = dynamic_cast<mitk::TransferFunctionProperty*>(this->GetDataNode()->GetProperty("Image Rendering.Transfer Function",renderer ));
594 
595  if( transferFunctionProp.IsNull() )
596  {
597  MITK_ERROR << "'Image Rendering.Mode'' was set to use a color transfer function but there is no property 'Image Rendering.Transfer Function'. Nothing will be done.";
598  return;
599  }
600  LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer);
601  //pass the transfer function to our level window filter
602  localStorage->m_LevelWindowFilter->SetLookupTable(transferFunctionProp->GetValue()->GetColorTransferFunction());
603 }
604 
606 {
607 
608  bool visible = true;
609  GetDataNode()->GetVisibility(visible, renderer, "visible");
610 
611  if ( !visible )
612  {
613  return;
614  }
615 
616  mitk::Image* data = const_cast<mitk::Image *>( this->GetInput() );
617  if ( data == NULL )
618  {
619  return;
620  }
621 
622  // Calculate time step of the input data for the specified renderer (integer value)
623  this->CalculateTimeStep( renderer );
624 
625  // Check if time step is valid
626  const TimeGeometry *dataTimeGeometry = data->GetTimeGeometry();
627  if ( ( dataTimeGeometry == NULL )
628  || ( dataTimeGeometry->CountTimeSteps() == 0 )
629  || ( !dataTimeGeometry->IsValidTimeStep( this->GetTimestep() ) ) )
630  {
631  return;
632  }
633 
634  const DataNode *node = this->GetDataNode();
635  data->UpdateOutputInformation();
636  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
637 
638  //check if something important has changed and we need to rerender
639  if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified?
640  || (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) //Was the data modified?
641  || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldPlaneGeometryUpdateTime()) //was the geometry modified?
642  || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldPlaneGeometry()->GetMTime())
643  || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified?
644  || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) )
645  {
646  this->GenerateDataForRenderer( renderer );
647  }
648 
649  // since we have checked that nothing important has changed, we can set
650  // m_LastUpdateTime to the current time
651  localStorage->m_LastUpdateTime.Modified();
652 }
653 
655 {
656  mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(node->GetData());
657 
658  // Properties common for both images and segmentations
659  node->AddProperty( "depthOffset", mitk::FloatProperty::New( 0.0 ), renderer, overwrite );
660  node->AddProperty( "outline binary", mitk::BoolProperty::New( false ), renderer, overwrite );
661  node->AddProperty( "outline width", mitk::FloatProperty::New( 1.0 ), renderer, overwrite );
662  node->AddProperty( "outline binary shadow", mitk::BoolProperty::New( false ), renderer, overwrite );
663  node->AddProperty( "outline binary shadow color", ColorProperty::New(0.0,0.0,0.0), renderer, overwrite );
664  node->AddProperty( "outline shadow width", mitk::FloatProperty::New( 1.5 ), renderer, overwrite );
665  if(image->IsRotated()) node->AddProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New(VTK_RESLICE_CUBIC) );
666  else node->AddProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New() );
667  node->AddProperty( "texture interpolation", mitk::BoolProperty::New( mitk::DataNodeFactory::m_TextureInterpolationActive ) ); // set to user configurable default value (see global options)
668  node->AddProperty( "in plane resample extent by geometry", mitk::BoolProperty::New( false ) );
669  node->AddProperty( "bounding box", mitk::BoolProperty::New( false ) );
670 
672  node->AddProperty( "Image Rendering.Mode", renderingModeProperty);
673 
674  // Set default grayscale look-up table
676  mitkLut->SetType(mitk::LookupTable::GRAYSCALE);
678  mitkLutProp->SetLookupTable(mitkLut);
679  node->SetProperty("LookupTable", mitkLutProp);
680 
681  std::string photometricInterpretation; // DICOM tag telling us how pixel values should be displayed
682  if ( node->GetStringProperty( "dicom.pixel.PhotometricInterpretation", photometricInterpretation ) )
683  {
684  // modality provided by DICOM or other reader
685  if ( photometricInterpretation.find("MONOCHROME1") != std::string::npos ) // meaning: display MINIMUM pixels as WHITE
686  {
687  // Set inverse grayscale look-up table
688  mitkLut->SetType(mitk::LookupTable::INVERSE_GRAYSCALE);
689  mitkLutProp->SetLookupTable(mitkLut);
690  node->SetProperty("LookupTable", mitkLutProp);
691  }
692  // Otherwise do nothing - the default grayscale look-up table has already been set
693  }
694 
695  bool isBinaryImage(false);
696  if ( ! node->GetBoolProperty("binary", isBinaryImage) )
697  {
698 
699  // ok, property is not set, use heuristic to determine if this
700  // is a binary image
701  mitk::Image::Pointer centralSliceImage;
702  ScalarType minValue = 0.0;
703  ScalarType maxValue = 0.0;
704  ScalarType min2ndValue = 0.0;
705  ScalarType max2ndValue = 0.0;
707 
708  sliceSelector->SetInput(image);
709  sliceSelector->SetSliceNr(image->GetDimension(2)/2);
710  sliceSelector->SetTimeNr(image->GetDimension(3)/2);
711  sliceSelector->SetChannelNr(image->GetDimension(4)/2);
712  sliceSelector->Update();
713  centralSliceImage = sliceSelector->GetOutput();
714  if ( centralSliceImage.IsNotNull() && centralSliceImage->IsInitialized() )
715  {
716  minValue = centralSliceImage->GetStatistics()->GetScalarValueMin();
717  maxValue = centralSliceImage->GetStatistics()->GetScalarValueMax();
718  min2ndValue = centralSliceImage->GetStatistics()->GetScalarValue2ndMin();
719  max2ndValue = centralSliceImage->GetStatistics()->GetScalarValue2ndMax();
720  }
721  if ((maxValue == min2ndValue && minValue == max2ndValue) || minValue == maxValue)
722  {
723  // centralSlice is strange, lets look at all data
724  minValue = image->GetStatistics()->GetScalarValueMin();
725  maxValue = image->GetStatistics()->GetScalarValueMaxNoRecompute();
726  min2ndValue = image->GetStatistics()->GetScalarValue2ndMinNoRecompute();
727  max2ndValue = image->GetStatistics()->GetScalarValue2ndMaxNoRecompute();
728  }
729  isBinaryImage = ( maxValue == min2ndValue && minValue == max2ndValue );
730  }
731 
732  // some more properties specific for a binary...
733  if (isBinaryImage)
734  {
735  node->AddProperty( "opacity", mitk::FloatProperty::New(0.3f), renderer, overwrite );
736  node->AddProperty( "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
737  node->AddProperty( "binaryimage.selectedcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
738  node->AddProperty( "binaryimage.selectedannotationcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
739  node->AddProperty( "binaryimage.hoveringcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
740  node->AddProperty( "binaryimage.hoveringannotationcolor", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
741  node->AddProperty( "binary", mitk::BoolProperty::New( true ), renderer, overwrite );
742  node->AddProperty("layer", mitk::IntProperty::New(10), renderer, overwrite);
743  }
744  else //...or image type object
745  {
746  node->AddProperty( "opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite );
747  node->AddProperty( "color", ColorProperty::New(1.0,1.0,1.0), renderer, overwrite );
748  node->AddProperty( "binary", mitk::BoolProperty::New( false ), renderer, overwrite );
749  node->AddProperty("layer", mitk::IntProperty::New(0), renderer, overwrite);
750 
751  std::string className = image->GetNameOfClass();
752 
753  if (className != "TensorImage" && className != "QBallImage")
754  {
755  PixelType pixelType = image->GetPixelType();
756  size_t numComponents = pixelType.GetNumberOfComponents();
757 
758  if ((pixelType.GetPixelTypeAsString() == "vector" && numComponents > 1) || numComponents == 2 || numComponents > 4)
759  node->AddProperty("Image.Displayed Component", mitk::IntProperty::New(0), renderer, overwrite);
760  }
761  }
762 
763  if(image.IsNotNull() && image->IsInitialized())
764  {
765  if((overwrite) || (node->GetProperty("levelwindow", renderer)==NULL))
766  {
767  /* initialize level/window from DICOM tags */
768  std::string sLevel;
769  std::string sWindow;
770 
771  if (GetBackwardsCompatibleDICOMProperty(0x0028, 0x1050, "dicom.voilut.WindowCenter", image->GetPropertyList(), sLevel)
772  && GetBackwardsCompatibleDICOMProperty(0x0028, 0x1051, "dicom.voilut.WindowWidth", image->GetPropertyList(), sWindow))
773  {
774  float level = atof( sLevel.c_str() );
775  float window = atof( sWindow.c_str() );
776 
777  mitk::LevelWindow contrast;
778  std::string sSmallestPixelValueInSeries;
779  std::string sLargestPixelValueInSeries;
780 
781  if (GetBackwardsCompatibleDICOMProperty(0x0028, 0x0108, "dicom.series.SmallestPixelValueInSeries", image->GetPropertyList(), sSmallestPixelValueInSeries)
782  && GetBackwardsCompatibleDICOMProperty(0x0028, 0x0109, "dicom.series.LargestPixelValueInSeries", image->GetPropertyList(), sLargestPixelValueInSeries))
783  {
784  float smallestPixelValueInSeries = atof( sSmallestPixelValueInSeries.c_str() );
785  float largestPixelValueInSeries = atof( sLargestPixelValueInSeries.c_str() );
786  contrast.SetRangeMinMax( smallestPixelValueInSeries-1, largestPixelValueInSeries+1 ); // why not a little buffer?
787  // might remedy some l/w widget challenges
788  }
789  else
790  {
791  contrast.SetAuto( static_cast<mitk::Image*>(node->GetData()), false, true ); // we need this as a fallback
792  }
793 
794  contrast.SetLevelWindow( level, window, true );
795  node->SetProperty( "levelwindow", LevelWindowProperty::New( contrast ), renderer );
796  }
797  }
798  if(((overwrite) || (node->GetProperty("opaclevelwindow", renderer)==NULL))
799  && (image->GetPixelType().GetPixelType() == itk::ImageIOBase::RGBA)
800  && (image->GetPixelType().GetComponentType() == itk::ImageIOBase::UCHAR) )
801  {
802  mitk::LevelWindow opaclevwin;
803  opaclevwin.SetRangeMinMax(0,255);
804  opaclevwin.SetWindowBounds(0,255);
806  node->SetProperty( "opaclevelwindow", prop, renderer );
807  }
808  }
809  Superclass::SetDefaultProperties(node, renderer, overwrite);
810 }
811 
813 {
814  return m_LSH.GetLocalStorage(renderer);
815 }
816 
817 
819 {
820  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); //the points to draw
821  vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New(); //the lines to connect the points
822  vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
823  colors->SetNumberOfComponents(3);
824  colors->SetName("Colors");
825 
826  float pref;
827  this->GetDataNode()->GetFloatProperty(mitk::RTConstants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),pref);
828 
830  mitk::IsoDoseLevelSet::Pointer isoDoseLevelSet = propIsoSet->GetValue();
831 
832  for(mitk::IsoDoseLevelSet::ConstIterator doseIT = isoDoseLevelSet->Begin(); doseIT!=isoDoseLevelSet->End();++doseIT)
833  {
834  if(doseIT->GetVisibleIsoLine())
835  {
836  this->CreateLevelOutline(renderer, &(doseIT.Value()), pref, points, lines, colors);
837  }//end of if visible dose value
838  }//end of loop over all does values
839 
841  mitk::IsoDoseLevelVector::Pointer frereIsoDoseLevelVec = propfreeIsoVec->GetValue();
842 
843  for(mitk::IsoDoseLevelVector::ConstIterator freeDoseIT = frereIsoDoseLevelVec->Begin(); freeDoseIT!=frereIsoDoseLevelVec->End();++freeDoseIT)
844  {
845  if(freeDoseIT->Value()->GetVisibleIsoLine())
846  {
847  this->CreateLevelOutline(renderer, freeDoseIT->Value(), pref, points, lines, colors);
848  }//end of if visible dose value
849  }//end of loop over all does values
850 
851  // Create a polydata to store everything in
852  vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
853  // Add the points to the dataset
854  polyData->SetPoints(points);
855  // Add the lines to the dataset
856  polyData->SetLines(lines);
857  polyData->GetCellData()->SetScalars(colors);
858  return polyData;
859 }
860 
861 void mitk::DoseImageVtkMapper2D::CreateLevelOutline(mitk::BaseRenderer* renderer, const mitk::IsoDoseLevel* level, float pref, vtkSmartPointer<vtkPoints> points, vtkSmartPointer<vtkCellArray> lines, vtkSmartPointer<vtkUnsignedCharArray> colors)
862 {
863  LocalStorage* localStorage = this->GetLocalStorage(renderer);
864 
865  //get the min and max index values of each direction
866  int* extent = localStorage->m_ReslicedImage->GetExtent();
867  int xMin = extent[0];
868  int xMax = extent[1];
869  int yMin = extent[2];
870  int yMax = extent[3];
871 
872  int* dims = localStorage->m_ReslicedImage->GetDimensions(); //dimensions of the image
873  int line = dims[0]; //how many pixels per line?
874  //get the depth for each contour
875  float depth = CalculateLayerDepth(renderer);
876 
877  double doseValue = level->GetDoseValue()*pref;
878  mitk::IsoDoseLevel::ColorType isoColor = level->GetColor();
879  unsigned char colorLine[3] = {static_cast<unsigned char>(isoColor.GetRed()*255),
880  static_cast<unsigned char>(isoColor.GetGreen()*255),
881  static_cast<unsigned char>(isoColor.GetBlue()*255)};
882 
883  int x = xMin; //pixel index x
884  int y = yMin; //pixel index y
885  float* currentPixel;
886 
887  // We take the pointer to the first pixel of the image
888  currentPixel = static_cast<float*>(localStorage->m_ReslicedImage->GetScalarPointer() );
889 
890  while (y <= yMax)
891  {
892  //if the current pixel value is set to something
893  if ((currentPixel) && (*currentPixel >= doseValue))
894  {
895  //check in which direction a line is necessary
896  //a line is added if the neighbor of the current pixel has the value 0
897  //and if the pixel is located at the edge of the image
898 
899  //if vvvvv not the first line vvvvv
900  if (y > yMin && *(currentPixel-line) < doseValue)
901  { //x direction - bottom edge of the pixel
902  //add the 2 points
903  vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
904  vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
905  //add the line between both points
906  lines->InsertNextCell(2);
907  lines->InsertCellPoint(p1);
908  lines->InsertCellPoint(p2);
909  colors->InsertNextTupleValue(colorLine);
910  }
911 
912  //if vvvvv not the last line vvvvv
913  if (y < yMax && *(currentPixel+line) < doseValue)
914  { //x direction - top edge of the pixel
915  vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
916  vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
917  lines->InsertNextCell(2);
918  lines->InsertCellPoint(p1);
919  lines->InsertCellPoint(p2);
920  colors->InsertNextTupleValue(colorLine);
921  }
922 
923  //if vvvvv not the first pixel vvvvv
924  if ( (x > xMin || y > yMin) && *(currentPixel-1) < doseValue)
925  { //y direction - left edge of the pixel
926  vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
927  vtkIdType p2 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
928  lines->InsertNextCell(2);
929  lines->InsertCellPoint(p1);
930  lines->InsertCellPoint(p2);
931  colors->InsertNextTupleValue(colorLine);
932  }
933 
934  //if vvvvv not the last pixel vvvvv
935  if ( (y < yMax || (x < xMax) ) && *(currentPixel+1) < doseValue)
936  { //y direction - right edge of the pixel
937  vtkIdType p1 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
938  vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
939  lines->InsertNextCell(2);
940  lines->InsertCellPoint(p1);
941  lines->InsertCellPoint(p2);
942  colors->InsertNextTupleValue(colorLine);
943  }
944 
945  /* now consider pixels at the edge of the image */
946 
947  //if vvvvv left edge of image vvvvv
948  if (x == xMin)
949  { //draw left edge of the pixel
950  vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
951  vtkIdType p2 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
952  lines->InsertNextCell(2);
953  lines->InsertCellPoint(p1);
954  lines->InsertCellPoint(p2);
955  colors->InsertNextTupleValue(colorLine);
956  }
957 
958  //if vvvvv right edge of image vvvvv
959  if (x == xMax)
960  { //draw right edge of the pixel
961  vtkIdType p1 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
962  vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
963  lines->InsertNextCell(2);
964  lines->InsertCellPoint(p1);
965  lines->InsertCellPoint(p2);
966  colors->InsertNextTupleValue(colorLine);
967  }
968 
969  //if vvvvv bottom edge of image vvvvv
970  if (y == yMin)
971  { //draw bottom edge of the pixel
972  vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
973  vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], y*localStorage->m_mmPerPixel[1], depth);
974  lines->InsertNextCell(2);
975  lines->InsertCellPoint(p1);
976  lines->InsertCellPoint(p2);
977  colors->InsertNextTupleValue(colorLine);
978  }
979 
980  //if vvvvv top edge of image vvvvv
981  if (y == yMax)
982  { //draw top edge of the pixel
983  vtkIdType p1 = points->InsertNextPoint(x*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
984  vtkIdType p2 = points->InsertNextPoint((x+1)*localStorage->m_mmPerPixel[0], (y+1)*localStorage->m_mmPerPixel[1], depth);
985  lines->InsertNextCell(2);
986  lines->InsertCellPoint(p1);
987  lines->InsertCellPoint(p2);
988  colors->InsertNextTupleValue(colorLine);
989  }
990  }//end if currentpixel is set
991 
992  x++;
993 
994  if (x > xMax)
995  { //reached end of line
996  x = xMin;
997  y++;
998  }
999 
1000  // Increase the pointer-position to the next pixel.
1001  // This is safe, as the while-loop and the x-reset logic above makes
1002  // sure we do not exceed the bounds of the image
1003  currentPixel++;
1004  }//end of while
1005 }
1006 
1008 {
1009  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
1010  //get the transformation matrix of the reslicer in order to render the slice as axial, coronal or saggital
1011  vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
1012  vtkSmartPointer<vtkMatrix4x4> matrix = localStorage->m_Reslicer->GetResliceAxes();
1013  trans->SetMatrix(matrix);
1014  //transform the plane/contour (the actual actor) to the corresponding view (axial, coronal or saggital)
1015  localStorage->m_Actor->SetUserTransform(trans);
1016  //transform the origin to center based coordinates, because MITK is center based.
1017  localStorage->m_Actor->SetPosition( -0.5*localStorage->m_mmPerPixel[0], -0.5*localStorage->m_mmPerPixel[1], 0.0);
1018 
1019  if ( localStorage->m_Actors->GetNumberOfPaths() > 1 )
1020  {
1021  vtkActor* secondaryActor = dynamic_cast<vtkActor*>( localStorage->m_Actors->GetParts()->GetItemAsObject(0) );
1022  secondaryActor->SetUserTransform(trans);
1023  secondaryActor->SetPosition( -0.5*localStorage->m_mmPerPixel[0], -0.5*localStorage->m_mmPerPixel[1], 0.0);
1024  }
1025 }
1026 
1028 {
1029  // if either one of the two geometries is NULL we return true
1030  // for safety reasons
1031  if ( renderingGeometry == NULL || imageGeometry == NULL )
1032  return true;
1033 
1034  // get the distance for the first cornerpoint
1035  ScalarType initialDistance = renderingGeometry->SignedDistance( imageGeometry->GetCornerPoint( 0 ) );
1036  for( int i=1; i<8; i++ )
1037  {
1038  mitk::Point3D cornerPoint = imageGeometry->GetCornerPoint( i );
1039 
1040  // get the distance to the other cornerpoints
1041  ScalarType distance = renderingGeometry->SignedDistance( cornerPoint );
1042 
1043  // if it has not the same signing as the distance of the first point
1044  if ( initialDistance * distance < 0 )
1045  {
1046  // we have an intersection and return true
1047  return true;
1048  }
1049  }
1050 
1051  // all distances have the same sign, no intersection and we return false
1052  return false;
1053 }
1054 
1056 {
1057 }
1058 
1060 : m_VectorComponentExtractor(vtkSmartPointer<vtkImageExtractComponents>::New())
1061 {
1062 
1064 
1065  //Do as much actions as possible in here to avoid double executions.
1079 
1080  //the following actions are always the same and thus can be performed
1081  //in the constructor for each image (i.e. the image-corresponding local storage)
1082  m_TSFilter->ReleaseDataFlagOn();
1083 
1085  //built a default lookuptable
1086  mitkLUT->SetType(mitk::LookupTable::GRAYSCALE);
1087  m_DefaultLookupTable = mitkLUT->GetVtkLookupTable();
1088 
1089  mitkLUT->SetType(mitk::LookupTable::LEGACY_BINARY);
1090  m_BinaryLookupTable = mitkLUT->GetVtkLookupTable();
1091 
1092  mitkLUT->SetType(mitk::LookupTable::LEGACY_RAINBOW_COLOR);
1093  m_ColorLookupTable = mitkLUT->GetVtkLookupTable();
1094 
1095  //do not repeat the texture (the image)
1096  m_Texture->RepeatOff();
1097 
1098  //set the mapper for the actor
1099  m_Actor->SetMapper( m_Mapper );
1100 
1101  vtkSmartPointer<vtkActor> outlineShadowActor = vtkSmartPointer<vtkActor>::New();
1102  outlineShadowActor->SetMapper( m_Mapper );
1103 
1104  m_Actors->AddPart( outlineShadowActor );
1105  m_Actors->AddPart( m_Actor );
1106 }
void SetWindowBounds(ScalarType lowerBound, ScalarType upperBound, bool expandRangesIfNecessary=true)
void ApplyLookuptable(mitk::BaseRenderer *renderer)
This method applies (or modifies) the lookuptable for all types of images.
itk::TimeStamp m_LastUpdateTime
Timestamp of last update of stored data.
mitk::PropertyList * GetPropertyList(const mitk::BaseRenderer *renderer=nullptr) const
Get the PropertyList of the renderer. If renderer is NULL, the BaseRenderer-independent PropertyList ...
The TransferFunctionProperty class Property class for the mitk::TransferFunction. ...
virtual DataNode * GetCurrentWorldPlaneGeometryNode()
Get a DataNode pointing to a data object containing the current 2D-worldgeometry. ...
static char * line
Definition: svm.cpp:2884
itk::SmartPointer< Self > Pointer
LocalStorage * GetLocalStorage(mitk::BaseRenderer *renderer)
Get the LocalStorage corresponding to the current renderer.
ScalarType GetLowerWindowBound() const
vtkSmartPointer< vtkMitkLevelWindowFilter > m_LevelWindowFilter
This filter is used to apply the level window to Grayvalue and RBG(A) images.
virtual unsigned long GetMTime() const override
Get the timestamp of the last change of the map or the last change of one of the properties store in ...
static Pointer New()
static const std::string REFERENCE_DOSE_PROPERTY_NAME
virtual DoseValueType GetDoseValue() const
virtual bool IsValid() const
Is this BaseGeometry in a state that is valid?
#define MITK_ERROR
Definition: mitkLogMacros.h:24
double ScalarType
std::string GetPixelTypeAsString() const
Returns a string containing the ITK pixel type name.
bool GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for int properties (instances of IntProperty)
static bool CalculateClippedPlaneBounds(const BaseGeometry *boundingGeometry, const PlaneGeometry *planeGeometry, double *bounds)
Calculate the bounding box of the resliced image. This is necessary for arbitrarily rotated planes in...
vtkSmartPointer< vtkPolyDataMapper > m_Mapper
Mapper of a 2D render window.
static Pointer New()
virtual void Update(mitk::BaseRenderer *renderer)
Checks whether this mapper needs to update itself and generate data.
Organizes the rendering process.
virtual ScalarType SignedDistance(const Point3D &pt3d_mm) const
bool GetBoolProperty(const char *propertyKey, bool &boolValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for bool properties (instances of BoolProperty)
const mitk::Image * GetInput(void)
Get the Image to map.
vtkSmartPointer< vtkImageExtractComponents > m_VectorComponentExtractor
vtkSmartPointer< vtkTexture > m_Texture
The texture which is used to render the current slice.
vtkSmartPointer< vtkLookupTable > m_ColorLookupTable
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
static Pointer New()
static const std::string DOSE_FREE_ISO_VALUES_PROPERTY_NAME
virtual const PlaneGeometry * GetCurrentWorldPlaneGeometry()
Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering.
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
Definition: mitkBaseData.h:52
static const std::string DOSE_ISO_LEVELS_PROPERTY_NAME
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
vtkSmartPointer< vtkImageData > m_ReslicedImage
Current slice of a 2D render window.
Property class for dose iso level sets.
static Pointer New()
void GeneratePlane(mitk::BaseRenderer *renderer, double planeBounds[6])
Generates a plane according to the size of the resliced image in milimeters.
mitk::BaseProperty * GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer=nullptr) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList of the rendere...
static bool m_TextureInterpolationActive
virtual unsigned long GetMTime() const override
Get the timestamp of the last change of the contents of this node or the referenced BaseData...
void ApplyColor(mitk::BaseRenderer *renderer)
Set the color of the image/polydata.
vtkSmartPointer< vtkPolyData > m_EmptyPolyData
Empty vtkPolyData that is set when rendering geometry does not intersect the image geometry...
vtkSmartPointer< vtkPolyData > CreateOutlinePolyData(mitk::BaseRenderer *renderer)
Generates a vtkPolyData object containing the outline of a given binary slice.
void ApplyColorTransferFunction(mitk::BaseRenderer *renderer)
This method applies a color transfer function. Internally, a vtkColorTransferFunction is used...
mitk::ScalarType * m_mmPerPixel
mmPerPixel relation between pixel and mm. (World spacing).
Vector3D GetNormal() const
Normal of the plane.
bool GetStringProperty(const char *propertyKey, std::string &string, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for string properties (instances of StringProperty)
void SetRangeMinMax(ScalarType min, ScalarType max)
vtkSmartPointer< vtkLookupTable > m_DefaultLookupTable
The lookuptables for colors and level window.
The LevelWindow class Class to store level/window values.
static Pointer New()
virtual const PlaneGeometry * GetPlane()
Get the rectangular area that is used for transformation by m_VtkAbstractTransform and therewith defi...
float CalculateLayerDepth(mitk::BaseRenderer *renderer)
This method uses the vtkCamera clipping range and the layer property to calcualte the depth of the ob...
virtual vtkProp * GetVtkProp(mitk::BaseRenderer *renderer)
The ColorProperty class RGB color property.
vtkSmartPointer< vtkLookupTable > m_BinaryLookupTable
Stores values needed for the representation/visualization of dose iso levels.
void AddProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer=nullptr, bool overwrite=false)
Add the property (instance of BaseProperty) if it does not exist (or always ifoverwrite istrue) with ...
#define MITK_WARN
Definition: mitkLogMacros.h:23
The LookupTableProperty class Property to associate mitk::LookupTable to an mitk::DataNode.
Property class for dose iso level vector.
static Pointer New()
bool GetFloatProperty(const char *propertyKey, float &floatValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for float properties (instances of FloatProperty)
void ApplyLevelWindow(mitk::BaseRenderer *renderer)
ApplyLevelWindow Apply the level window for the given renderer.
vtkSmartPointer< vtkPlaneSource > m_Plane
Plane on which the slice is rendered as texture.
Image class for storing images.
Definition: mitkImage.h:76
Describes a geometry defined by an vtkAbstractTransform and a plane.
const mitk::PixelType GetPixelType(int n=0) const
Returns the PixelType of channel n.
Definition: mitkImage.cpp:105
void ApplyOpacity(mitk::BaseRenderer *renderer)
Set the opacity of the actor.
Internal class holding the mapper, actor, etc. for each of the 3 2D render windows.
Point3D GetCornerPoint(int id) const
Get the position of the corner number id (in world coordinates)
Describes the geometry of a data object consisting of slices.
::itk::RGBPixel< float > ColorType
static Pointer New()
void TransformActor(mitk::BaseRenderer *renderer)
Transforms the actor to the actual position in 3D.
bool RenderingGeometryIntersectsImage(const PlaneGeometry *renderingGeometry, SlicedGeometry3D *imageGeometry)
Calculates whether the given rendering geometry intersects the given SlicedGeometry3D.
mitk::ExtractSliceFilter::Pointer m_Reslicer
The actual reslicer (one per renderer)
bool HasReferenceGeometry() const
static Pointer New()
~LocalStorage()
Default deconstructor of the local storage.
virtual ColorType GetColor() const
vcl_size_t GetNumberOfComponents() const
Get the number of components of which each element consists.
virtual BaseGeometry::Pointer GetGeometryForTimeStep(TimeStepType timeStep) const =0
Returns the geometry which corresponds to the given time step.
virtual void GenerateDataForRenderer(mitk::BaseRenderer *renderer)
Does the actual resampling, without rendering the image yet. All the data is generated inside this me...
virtual bool IsInitialized() const
Check whether the data has been initialized, i.e., at least the Geometry and other header data has be...
vtkSmartPointer< vtkPolyData > m_OutlinePolyData
PolyData object containg all lines/points needed for outlining the contour. This container is used to...
vtkSmartPointer< vtkActor > m_Actor
Actor of a 2D render window.
void ApplyRenderingMode(mitk::BaseRenderer *renderer)
This method switches between different rendering modes (e.g. use a lookup table or a transfer functio...
unsigned long GetCurrentWorldPlaneGeometryUpdateTime()
Get timestamp of last call of SetCurrentWorldPlaneGeometry.
SlicedGeometry3D * GetSlicedGeometry(unsigned int t=0) const
Convenience access method for the geometry, which is of type SlicedGeometry3D (or a sub-class of it)...
Describes a two-dimensional, rectangular plane.
void SetProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer=nullptr)
Set the property (instance of BaseProperty) with key propertyKey in the PropertyList of the renderer ...
ScalarType GetUpperWindowBound() const
virtual void UpdateOutputInformation() override
unsigned int GetDimension() const
Get dimension of the image.
Definition: mitkImage.cpp:110
static Pointer New()
vtkRenderer * GetVtkRenderer() const
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
Definition: mitkBaseData.h:129
LocalStorage()
Default constructor of the local storage.
bool MITKCORE_EXPORT GetBackwardsCompatibleDICOMProperty(unsigned int group, unsigned int element, std::string const &backwardsCompatiblePropertyName, PropertyList const *propertyList, std::string &propertyValue)
vtkSmartPointer< vtkMitkThickSlicesFilter > m_TSFilter
Filter for thick slices.
virtual bool IsValidTimeStep(TimeStepType timeStep) const =0
Test for the given time step if a geometry is availible.
static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer=NULL, bool overwrite=false)
Set the default properties for general image rendering.
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
Class for defining the data type of pixels.
Definition: mitkPixelType.h:55
virtual IdType GetValueAsId() const
vtkSmartPointer< vtkPropAssembly > m_Actors
virtual T GetValue() const
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.