Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkLabelSetImageVtkMapper2D.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 
18 
19 // MITK
21 #include <mitkDataNode.h>
22 #include <mitkImageSliceSelector.h>
26 #include <mitkPixelType.h>
27 #include <mitkPlaneClipping.h>
28 #include <mitkPlaneGeometry.h>
29 #include <mitkProperties.h>
31 #include <mitkTimeSlicedGeometry.h>
34 
35 // MITK Rendering
39 
40 // VTK
41 #include <vtkCamera.h>
42 #include <vtkCellArray.h>
43 #include <vtkImageData.h>
44 #include <vtkImageReslice.h>
45 #include <vtkLookupTable.h>
46 #include <vtkMatrix4x4.h>
47 #include <vtkPlaneSource.h>
48 #include <vtkPoints.h>
49 #include <vtkPolyData.h>
50 #include <vtkPolyDataMapper.h>
51 #include <vtkProperty.h>
52 #include <vtkTransform.h>
53 //#include <vtkOpenGLTexture.h>
54 
55 // ITK
56 #include <itkRGBAPixel.h>
58 
60 {
61 }
62 
64 {
65 }
66 
68 {
69  // return the actor corresponding to the renderer
70  return m_LSH.GetLocalStorage(renderer)->m_Actors;
71 }
72 
74  mitk::BaseRenderer *renderer)
75 {
76  return m_LSH.GetLocalStorage(renderer);
77 }
78 
80 {
81  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
82  mitk::DataNode *node = this->GetDataNode();
83  mitk::LabelSetImage *image = dynamic_cast<mitk::LabelSetImage *>(node->GetData());
84  assert(image && image->IsInitialized());
85 
86  // check if there is a valid worldGeometry
87  const PlaneGeometry *worldGeometry = renderer->GetCurrentWorldPlaneGeometry();
88  if ((worldGeometry == NULL) || (!worldGeometry->IsValid()) || (!worldGeometry->HasReferenceGeometry()))
89  return;
90 
91  image->Update();
92 
93  int numberOfLayers = image->GetNumberOfLayers();
94  int activeLayer = image->GetActiveLayer();
95 
96  float opacity = 1.0f;
97  node->GetOpacity(opacity, renderer, "opacity");
98 
99  if (numberOfLayers != localStorage->m_NumberOfLayers)
100  {
101  localStorage->m_NumberOfLayers = numberOfLayers;
102  localStorage->m_ReslicedImageVector.clear();
103  localStorage->m_ReslicerVector.clear();
104  localStorage->m_LayerTextureVector.clear();
105  localStorage->m_LevelWindowFilterVector.clear();
106  localStorage->m_LayerMapperVector.clear();
107  localStorage->m_LayerActorVector.clear();
108 
110 
111  for (int lidx = 0; lidx < numberOfLayers; ++lidx)
112  {
114  localStorage->m_ReslicerVector.push_back(mitk::ExtractSliceFilter::New());
118  localStorage->m_LayerActorVector.push_back(vtkSmartPointer<vtkActor>::New());
119 
120  // do not repeat the texture (the image)
121  localStorage->m_LayerTextureVector[lidx]->RepeatOff();
122 
123  // set corresponding mappers for the actors
124  localStorage->m_LayerActorVector[lidx]->SetMapper(localStorage->m_LayerMapperVector[lidx]);
125 
126  localStorage->m_Actors->AddPart(localStorage->m_LayerActorVector[lidx]);
127  }
128 
129  localStorage->m_Actors->AddPart(localStorage->m_OutlineShadowActor);
130  localStorage->m_Actors->AddPart(localStorage->m_OutlineActor);
131  }
132 
133  // early out if there is no intersection of the current rendering geometry
134  // and the geometry of the image that is to be rendered.
135  if (!RenderingGeometryIntersectsImage(worldGeometry, image->GetSlicedGeometry()))
136  {
137  // set image to NULL, to clear the texture in 3D, because
138  // the latest image is used there if the plane is out of the geometry
139  // see bug-13275
140  for (int lidx = 0; lidx < numberOfLayers; ++lidx)
141  {
142  localStorage->m_ReslicedImageVector[lidx] = NULL;
143  localStorage->m_LayerMapperVector[lidx]->SetInputData(localStorage->m_EmptyPolyData);
144  localStorage->m_OutlineActor->SetVisibility(false);
145  localStorage->m_OutlineShadowActor->SetVisibility(false);
146  }
147  return;
148  }
149 
150  for (int lidx = 0; lidx < numberOfLayers; ++lidx)
151  {
152  mitk::Image *layerImage = NULL;
153 
154  // set main input for ExtractSliceFilter
155  if (lidx == activeLayer)
156  layerImage = image;
157  else
158  layerImage = image->GetLayerImage(lidx);
159 
160  localStorage->m_ReslicerVector[lidx]->SetInput(layerImage);
161  localStorage->m_ReslicerVector[lidx]->SetWorldGeometry(worldGeometry);
162  localStorage->m_ReslicerVector[lidx]->SetTimeStep(this->GetTimestep());
163 
164  // set the transformation of the image to adapt reslice axis
165  localStorage->m_ReslicerVector[lidx]->SetResliceTransformByGeometry(
166  layerImage->GetTimeGeometry()->GetGeometryForTimeStep(this->GetTimestep()));
167 
168  // is the geometry of the slice based on the image image or the worldgeometry?
169  bool inPlaneResampleExtentByGeometry = false;
170  node->GetBoolProperty("in plane resample extent by geometry", inPlaneResampleExtentByGeometry, renderer);
171  localStorage->m_ReslicerVector[lidx]->SetInPlaneResampleExtentByGeometry(inPlaneResampleExtentByGeometry);
172  localStorage->m_ReslicerVector[lidx]->SetInterpolationMode(ExtractSliceFilter::RESLICE_NEAREST);
173  localStorage->m_ReslicerVector[lidx]->SetVtkOutputRequest(true);
174 
175  // this is needed when thick mode was enabled before. These variables have to be reset to default values
176  localStorage->m_ReslicerVector[lidx]->SetOutputDimensionality(2);
177  localStorage->m_ReslicerVector[lidx]->SetOutputSpacingZDirection(1.0);
178  localStorage->m_ReslicerVector[lidx]->SetOutputExtentZDirection(0, 0);
179 
180  // Bounds information for reslicing (only required if reference geometry is present)
181  // this used for generating a vtkPLaneSource with the right size
182  double sliceBounds[6];
183  sliceBounds[0] = 0.0;
184  sliceBounds[1] = 0.0;
185  sliceBounds[2] = 0.0;
186  sliceBounds[3] = 0.0;
187  sliceBounds[4] = 0.0;
188  sliceBounds[5] = 0.0;
189 
190  localStorage->m_ReslicerVector[lidx]->GetClippedPlaneBounds(sliceBounds);
191 
192  // setup the textured plane
193  this->GeneratePlane(renderer, sliceBounds);
194 
195  // get the spacing of the slice
196  localStorage->m_mmPerPixel = localStorage->m_ReslicerVector[lidx]->GetOutputSpacing();
197  localStorage->m_ReslicerVector[lidx]->Modified();
198  // start the pipeline with updating the largest possible, needed if the geometry of the image has changed
199  localStorage->m_ReslicerVector[lidx]->UpdateLargestPossibleRegion();
200  localStorage->m_ReslicedImageVector[lidx] = localStorage->m_ReslicerVector[lidx]->GetVtkOutput();
201 
202  const PlaneGeometry *planeGeometry = dynamic_cast<const PlaneGeometry *>(worldGeometry);
203 
204  double textureClippingBounds[6];
205  for (auto &textureClippingBound : textureClippingBounds)
206  {
207  textureClippingBound = 0.0;
208  }
209 
210  // Calculate the actual bounds of the transformed plane clipped by the
211  // dataset bounding box; this is required for drawing the texture at the
212  // correct position during 3D mapping.
213  mitk::PlaneClipping::CalculateClippedPlaneBounds(layerImage->GetGeometry(), planeGeometry, textureClippingBounds);
214 
215  textureClippingBounds[0] = static_cast<int>(textureClippingBounds[0] / localStorage->m_mmPerPixel[0] + 0.5);
216  textureClippingBounds[1] = static_cast<int>(textureClippingBounds[1] / localStorage->m_mmPerPixel[0] + 0.5);
217  textureClippingBounds[2] = static_cast<int>(textureClippingBounds[2] / localStorage->m_mmPerPixel[1] + 0.5);
218  textureClippingBounds[3] = static_cast<int>(textureClippingBounds[3] / localStorage->m_mmPerPixel[1] + 0.5);
219 
220  // clipping bounds for cutting the imageLayer
221  localStorage->m_LevelWindowFilterVector[lidx]->SetClippingBounds(textureClippingBounds);
222 
223  localStorage->m_LevelWindowFilterVector[lidx]->SetLookupTable(
224  image->GetLabelSet(lidx)->GetLookupTable()->GetVtkLookupTable());
225 
226  // do not use a VTK lookup table (we do that ourselves in m_LevelWindowFilter)
227  localStorage->m_LayerTextureVector[lidx]->MapColorScalarsThroughLookupTableOff();
228 
229  // connect the imageLayer with the levelwindow filter
230  localStorage->m_LevelWindowFilterVector[lidx]->SetInputData(localStorage->m_ReslicedImageVector[lidx]);
231  // connect the texture with the output of the levelwindow filter
232 
233  // check for texture interpolation property
234  bool textureInterpolation = false;
235  node->GetBoolProperty("texture interpolation", textureInterpolation, renderer);
236 
237  // set the interpolation modus according to the property
238  localStorage->m_LayerTextureVector[lidx]->SetInterpolate(textureInterpolation);
239 
240  localStorage->m_LayerTextureVector[lidx]->SetInputConnection(
241  localStorage->m_LevelWindowFilterVector[lidx]->GetOutputPort());
242 
243  this->TransformActor(renderer);
244 
245  // set the plane as input for the mapper
246  localStorage->m_LayerMapperVector[lidx]->SetInputConnection(localStorage->m_Plane->GetOutputPort());
247 
248  // set the texture for the actor
249  localStorage->m_LayerActorVector[lidx]->SetTexture(localStorage->m_LayerTextureVector[lidx]);
250  localStorage->m_LayerActorVector[lidx]->GetProperty()->SetOpacity(opacity);
251  }
252 
253  mitk::Label* activeLabel = image->GetActiveLabel(activeLayer);
254  if (nullptr != activeLabel)
255  {
256  bool contourActive = false;
257  node->GetBoolProperty("labelset.contour.active", contourActive, renderer);
258  if (contourActive && activeLabel->GetVisible()) //contour rendering
259  {
260  //generate contours/outlines
261  localStorage->m_OutlinePolyData =
262  this->CreateOutlinePolyData(renderer, localStorage->m_ReslicedImageVector[activeLayer], activeLabel->GetValue());
263  localStorage->m_OutlineActor->SetVisibility(true);
264  localStorage->m_OutlineShadowActor->SetVisibility(true);
265  const mitk::Color& color = activeLabel->GetColor();
266  localStorage->m_OutlineActor->GetProperty()->SetColor(color.GetRed(), color.GetGreen(), color.GetBlue());
267  localStorage->m_OutlineShadowActor->GetProperty()->SetColor(0, 0, 0);
268 
269  float contourWidth(2.0);
270  node->GetFloatProperty("labelset.contour.width", contourWidth, renderer);
271  localStorage->m_OutlineActor->GetProperty()->SetLineWidth(contourWidth);
272  localStorage->m_OutlineShadowActor->GetProperty()->SetLineWidth(contourWidth * 1.5);
273 
274  localStorage->m_OutlineActor->GetProperty()->SetOpacity(opacity);
275  localStorage->m_OutlineShadowActor->GetProperty()->SetOpacity(opacity);
276 
277  localStorage->m_OutlineMapper->SetInputData(localStorage->m_OutlinePolyData);
278  return;
279  }
280  }
281  localStorage->m_OutlineActor->SetVisibility(false);
282  localStorage->m_OutlineShadowActor->SetVisibility(false);
283 }
284 
286  SlicedGeometry3D *imageGeometry)
287 {
288  // if either one of the two geometries is NULL we return true
289  // for safety reasons
290  if (renderingGeometry == NULL || imageGeometry == NULL)
291  return true;
292 
293  // get the distance for the first cornerpoint
294  ScalarType initialDistance = renderingGeometry->SignedDistance(imageGeometry->GetCornerPoint(0));
295  for (int i = 1; i < 8; i++)
296  {
297  mitk::Point3D cornerPoint = imageGeometry->GetCornerPoint(i);
298 
299  // get the distance to the other cornerpoints
300  ScalarType distance = renderingGeometry->SignedDistance(cornerPoint);
301 
302  // if it has not the same signing as the distance of the first point
303  if (initialDistance * distance < 0)
304  {
305  // we have an intersection and return true
306  return true;
307  }
308  }
309 
310  // all distances have the same sign, no intersection and we return false
311  return false;
312 }
313 
315  vtkImageData *image,
316  int pixelValue)
317 {
318  LocalStorage *localStorage = this->GetLocalStorage(renderer);
319 
320  // get the min and max index values of each direction
321  int *extent = image->GetExtent();
322  int xMin = extent[0];
323  int xMax = extent[1];
324  int yMin = extent[2];
325  int yMax = extent[3];
326 
327  int *dims = image->GetDimensions(); // dimensions of the image
328  int line = dims[0]; // how many pixels per line?
329  int x = xMin; // pixel index x
330  int y = yMin; // pixel index y
331 
332  // get the depth for each contour
333  float depth = this->CalculateLayerDepth(renderer);
334 
335  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); // the points to draw
336  vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New(); // the lines to connect the points
337 
338  // We take the pointer to the first pixel of the image
339  mitk::Label::PixelType *currentPixel = static_cast<mitk::Label::PixelType *>(image->GetScalarPointer());
340 
341  while (y <= yMax)
342  {
343  // if the current pixel value is set to something
344  if ((currentPixel) && (*currentPixel == pixelValue))
345  {
346  // check in which direction a line is necessary
347  // a line is added if the neighbor of the current pixel has the value 0
348  // and if the pixel is located at the edge of the image
349 
350  // if vvvvv not the first line vvvvv
351  if (y > yMin && *(currentPixel - line) != pixelValue)
352  { // x direction - bottom edge of the pixel
353  // add the 2 points
354  vtkIdType p1 =
355  points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
356  vtkIdType p2 =
357  points->InsertNextPoint((x + 1) * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
358  // add the line between both points
359  lines->InsertNextCell(2);
360  lines->InsertCellPoint(p1);
361  lines->InsertCellPoint(p2);
362  }
363 
364  // if vvvvv not the last line vvvvv
365  if (y < yMax && *(currentPixel + line) != pixelValue)
366  { // x direction - top edge of the pixel
367  vtkIdType p1 =
368  points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
369  vtkIdType p2 = points->InsertNextPoint(
370  (x + 1) * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
371  lines->InsertNextCell(2);
372  lines->InsertCellPoint(p1);
373  lines->InsertCellPoint(p2);
374  }
375 
376  // if vvvvv not the first pixel vvvvv
377  if ((x > xMin || y > yMin) && *(currentPixel - 1) != pixelValue)
378  { // y direction - left edge of the pixel
379  vtkIdType p1 =
380  points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
381  vtkIdType p2 =
382  points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
383  lines->InsertNextCell(2);
384  lines->InsertCellPoint(p1);
385  lines->InsertCellPoint(p2);
386  }
387 
388  // if vvvvv not the last pixel vvvvv
389  if ((y < yMax || (x < xMax)) && *(currentPixel + 1) != pixelValue)
390  { // y direction - right edge of the pixel
391  vtkIdType p1 =
392  points->InsertNextPoint((x + 1) * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
393  vtkIdType p2 = points->InsertNextPoint(
394  (x + 1) * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
395  lines->InsertNextCell(2);
396  lines->InsertCellPoint(p1);
397  lines->InsertCellPoint(p2);
398  }
399 
400  /* now consider pixels at the edge of the image */
401 
402  // if vvvvv left edge of image vvvvv
403  if (x == xMin)
404  { // draw left edge of the pixel
405  vtkIdType p1 =
406  points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
407  vtkIdType p2 =
408  points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
409  lines->InsertNextCell(2);
410  lines->InsertCellPoint(p1);
411  lines->InsertCellPoint(p2);
412  }
413 
414  // if vvvvv right edge of image vvvvv
415  if (x == xMax)
416  { // draw right edge of the pixel
417  vtkIdType p1 =
418  points->InsertNextPoint((x + 1) * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
419  vtkIdType p2 = points->InsertNextPoint(
420  (x + 1) * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
421  lines->InsertNextCell(2);
422  lines->InsertCellPoint(p1);
423  lines->InsertCellPoint(p2);
424  }
425 
426  // if vvvvv bottom edge of image vvvvv
427  if (y == yMin)
428  { // draw bottom edge of the pixel
429  vtkIdType p1 =
430  points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
431  vtkIdType p2 =
432  points->InsertNextPoint((x + 1) * localStorage->m_mmPerPixel[0], y * localStorage->m_mmPerPixel[1], depth);
433  lines->InsertNextCell(2);
434  lines->InsertCellPoint(p1);
435  lines->InsertCellPoint(p2);
436  }
437 
438  // if vvvvv top edge of image vvvvv
439  if (y == yMax)
440  { // draw top edge of the pixel
441  vtkIdType p1 =
442  points->InsertNextPoint(x * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
443  vtkIdType p2 = points->InsertNextPoint(
444  (x + 1) * localStorage->m_mmPerPixel[0], (y + 1) * localStorage->m_mmPerPixel[1], depth);
445  lines->InsertNextCell(2);
446  lines->InsertCellPoint(p1);
447  lines->InsertCellPoint(p2);
448  }
449  } // end if currentpixel is set
450 
451  x++;
452 
453  if (x > xMax)
454  { // reached end of line
455  x = xMin;
456  y++;
457  }
458 
459  // Increase the pointer-position to the next pixel.
460  // This is safe, as the while-loop and the x-reset logic above makes
461  // sure we do not exceed the bounds of the image
462  currentPixel++;
463  } // end of while
464 
465  // Create a polydata to store everything in
466  vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
467  // Add the points to the dataset
468  polyData->SetPoints(points);
469  // Add the lines to the dataset
470  polyData->SetLines(lines);
471  return polyData;
472 }
473 
475 {
476  LocalStorage *localStorage = this->GetLocalStorage(renderer);
477  localStorage->m_OutlineActor->GetProperty()->SetColor(color.GetRed(), color.GetGreen(), color.GetBlue());
478  localStorage->m_OutlineShadowActor->GetProperty()->SetColor(0, 0, 0);
479 }
480 
482 {
483  LocalStorage *localStorage = this->GetLocalStorage(renderer);
484  float opacity = 1.0f;
485  this->GetDataNode()->GetOpacity(opacity, renderer, "opacity");
486  localStorage->m_LayerActorVector[layer]->GetProperty()->SetOpacity(opacity);
487  localStorage->m_OutlineActor->GetProperty()->SetOpacity(opacity);
488  localStorage->m_OutlineShadowActor->GetProperty()->SetOpacity(opacity);
489 }
490 
492 {
493  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
494  mitk::LabelSetImage *input = dynamic_cast<mitk::LabelSetImage *>(this->GetDataNode()->GetData());
495  localStorage->m_LevelWindowFilterVector[layer]->SetLookupTable(
496  input->GetLabelSet(layer)->GetLookupTable()->GetVtkLookupTable());
497 }
498 
500 {
501  bool visible = true;
502  const DataNode *node = this->GetDataNode();
503  node->GetVisibility(visible, renderer, "visible");
504 
505  if (!visible)
506  return;
507 
508  mitk::LabelSetImage *image = dynamic_cast<mitk::LabelSetImage *>(node->GetData());
509 
510  if (image == NULL || image->IsInitialized() == false)
511  return;
512 
513  // Calculate time step of the image data for the specified renderer (integer value)
514  this->CalculateTimeStep(renderer);
515 
516  // Check if time step is valid
517  const TimeGeometry *dataTimeGeometry = image->GetTimeGeometry();
518  if ((dataTimeGeometry == NULL) || (dataTimeGeometry->CountTimeSteps() == 0) ||
519  (!dataTimeGeometry->IsValidTimeStep(this->GetTimestep())))
520  {
521  return;
522  }
523 
524  image->UpdateOutputInformation();
525  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
526 
527  // check if something important has changed and we need to re-render
528 
529  //(localStorage->m_LastDataUpdateTime < node->GetMTime()) // this one is too generic
530  if ((localStorage->m_LastDataUpdateTime < image->GetMTime()) // was the data modified?
531  ||
532  (localStorage->m_LastDataUpdateTime < image->GetPipelineMTime()) ||
533  (localStorage->m_LastDataUpdateTime <
534  renderer->GetCurrentWorldPlaneGeometryUpdateTime()) // was the geometry modified?
535  ||
536  (localStorage->m_LastDataUpdateTime < renderer->GetCurrentWorldPlaneGeometry()->GetMTime()))
537  {
538  this->GenerateDataForRenderer(renderer);
539  localStorage->m_LastDataUpdateTime.Modified();
540  }
541 }
542 
543 // set the two points defining the textured plane according to the dimension and spacing
545 {
546  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
547 
548  float depth = this->CalculateLayerDepth(renderer);
549  // Set the origin to (xMin; yMin; depth) of the plane. This is necessary for obtaining the correct
550  // plane size in crosshair rotation and swivel mode.
551  localStorage->m_Plane->SetOrigin(planeBounds[0], planeBounds[2], depth);
552  // These two points define the axes of the plane in combination with the origin.
553  // Point 1 is the x-axis and point 2 the y-axis.
554  // Each plane is transformed according to the view (axial, coronal and saggital) afterwards.
555  localStorage->m_Plane->SetPoint1(planeBounds[1], planeBounds[2], depth); // P1: (xMax, yMin, depth)
556  localStorage->m_Plane->SetPoint2(planeBounds[0], planeBounds[3], depth); // P2: (xMin, yMax, depth)
557 }
558 
560 {
561  // get the clipping range to check how deep into z direction we can render images
562  double maxRange = renderer->GetVtkRenderer()->GetActiveCamera()->GetClippingRange()[1];
563 
564  // Due to a VTK bug, we cannot use the whole clipping range. /100 is empirically determined
565  float depth = -maxRange * 0.01; // divide by 100
566  int layer = 0;
567  GetDataNode()->GetIntProperty("layer", layer, renderer);
568  // add the layer property for each image to render images with a higher layer on top of the others
569  depth += layer * 10; //*10: keep some room for each image (e.g. for QBalls in between)
570  if (depth > 0.0f)
571  {
572  depth = 0.0f;
573  MITK_WARN << "Layer value exceeds clipping range. Set to minimum instead.";
574  }
575  return depth;
576 }
577 
579 {
580  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);
581  // get the transformation matrix of the reslicer in order to render the slice as axial, coronal or saggital
582  vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
583  vtkSmartPointer<vtkMatrix4x4> matrix = localStorage->m_ReslicerVector[0]->GetResliceAxes(); // same for all layers
584  trans->SetMatrix(matrix);
585 
586  for (int lidx = 0; lidx < localStorage->m_NumberOfLayers; ++lidx)
587  {
588  // transform the plane/contour (the actual actor) to the corresponding view (axial, coronal or saggital)
589  localStorage->m_LayerActorVector[lidx]->SetUserTransform(trans);
590  // transform the origin to center based coordinates, because MITK is center based.
591  localStorage->m_LayerActorVector[lidx]->SetPosition(
592  -0.5 * localStorage->m_mmPerPixel[0], -0.5 * localStorage->m_mmPerPixel[1], 0.0);
593  }
594  // same for outline actor
595  localStorage->m_OutlineActor->SetUserTransform(trans);
596  localStorage->m_OutlineActor->SetPosition(
597  -0.5 * localStorage->m_mmPerPixel[0], -0.5 * localStorage->m_mmPerPixel[1], 0.0);
598  // same for outline shadow actor
599  localStorage->m_OutlineShadowActor->SetUserTransform(trans);
600  localStorage->m_OutlineShadowActor->SetPosition(
601  -0.5 * localStorage->m_mmPerPixel[0], -0.5 * localStorage->m_mmPerPixel[1], 0.0);
602 }
603 
605  mitk::BaseRenderer *renderer,
606  bool overwrite)
607 {
608  // add/replace the following properties
609  node->SetProperty("opacity", FloatProperty::New(1.0f), renderer);
610  node->SetProperty("binary", BoolProperty::New(false), renderer);
611 
612  mitk::RenderingModeProperty::Pointer renderingModeProperty =
614  node->SetProperty("Image Rendering.Mode", renderingModeProperty, renderer);
615 
616  mitk::LevelWindow levelwindow(32767.5, 65535);
618 
619  levWinProp->SetLevelWindow(levelwindow);
620  node->SetProperty("levelwindow", levWinProp, renderer);
621 
622  node->SetProperty("labelset.contour.active", BoolProperty::New(true), renderer);
623  node->SetProperty("labelset.contour.width", FloatProperty::New(2.0), renderer);
624 
625  Superclass::SetDefaultProperties(node, renderer, overwrite);
626 }
627 
629 {
630 }
631 
633 {
634  // Do as much actions as possible in here to avoid double executions.
637  m_OutlinePolyData = vtkSmartPointer<vtkPolyData>::New();
638  m_EmptyPolyData = vtkSmartPointer<vtkPolyData>::New();
639  m_OutlineActor = vtkSmartPointer<vtkActor>::New();
640  m_OutlineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
641  m_OutlineShadowActor = vtkSmartPointer<vtkActor>::New();
642 
643  m_NumberOfLayers = 0;
644 
645  m_OutlineActor->SetMapper(m_OutlineMapper);
646  m_OutlineShadowActor->SetMapper(m_OutlineMapper);
647 
648  m_OutlineActor->SetVisibility(false);
649  m_OutlineShadowActor->SetVisibility(false);
650 }
static char * line
Definition: svm.cpp:2884
static Pointer New()
LocalStorage()
Default constructor of the local storage.
double ScalarType
bool GetVisible() const
Definition: mitkLabel.cpp:123
virtual void GenerateDataForRenderer(mitk::BaseRenderer *renderer) override
Does the actual resampling, without rendering the image yet. All the data is generated inside this me...
vtkSmartPointer< vtkActor > m_OutlineActor
An actor for the outline.
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...
std::vector< vtkSmartPointer< vtkActor > > m_LayerActorVector
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)
bool RenderingGeometryIntersectsImage(const PlaneGeometry *renderingGeometry, SlicedGeometry3D *imageGeometry)
Calculates whether the given rendering geometry intersects the given SlicedGeometry3D.
virtual vtkProp * GetVtkProp(mitk::BaseRenderer *renderer) override
static Pointer New()
A data structure describing a label.
Definition: mitkLabel.h:35
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
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
std::vector< vtkSmartPointer< vtkImageData > > m_ReslicedImageVector
std::vector< vtkSmartPointer< vtkMitkLevelWindowFilter > > m_LevelWindowFilterVector
This filter is used to apply the level window to Grayvalue and RBG(A) images.
float CalculateLayerDepth(mitk::BaseRenderer *renderer)
This method uses the vtkCamera clipping range and the layer property to calcualte the depth of the ob...
The LevelWindow class Class to store level/window values.
virtual void Update(mitk::BaseRenderer *renderer) override
Checks whether this mapper needs to update itself and generate data.
static Pointer New()
LocalStorage * GetLocalStorage(mitk::BaseRenderer *renderer)
Get the LocalStorage corresponding to the current renderer.
#define MITK_WARN
Definition: mitkLogMacros.h:23
~LocalStorage()
Default deconstructor of the local storage.
bool GetOpacity(float &opacity, const mitk::BaseRenderer *renderer, const char *propertyKey="opacity") const
Convenience access method for opacity properties (instances of FloatProperty)
void ApplyOpacity(mitk::BaseRenderer *renderer, int layer)
Set the opacity of the actor.
vtkSmartPointer< vtkActor > m_OutlineShadowActor
An actor for the outline shadow.
bool GetFloatProperty(const char *propertyKey, float &floatValue, const mitk::BaseRenderer *renderer=nullptr) const
Convenience access method for float properties (instances of FloatProperty)
Image class for storing images.
Definition: mitkImage.h:76
unsigned int GetNumberOfLayers() const
mitk::ScalarType * m_mmPerPixel
mmPerPixel relation between pixel and mm. (World spacing).
mitk::Image * GetLayerImage(unsigned int layer)
mitk::Label * GetActiveLabel(unsigned int layer=0)
Returns the active label of a specific layer.
void TransformActor(mitk::BaseRenderer *renderer)
Transforms the actor to the actual position in 3D.
void ApplyColor(mitk::BaseRenderer *renderer, const mitk::Color &color)
Set the color of the image/polydata.
Point3D GetCornerPoint(int id) const
Get the position of the corner number id (in world coordinates)
virtual unsigned long GetMTime() const override
Get the modified time of the last change of the contents this data object or its geometry.
static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer=NULL, bool overwrite=false)
Set the default properties for general image rendering.
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
Describes the geometry of a data object consisting of slices.
Internal class holding the mapper, actor, etc. for each of the 3 2D render windows.
static Pointer New()
void ApplyLookuptable(mitk::BaseRenderer *renderer, int layer)
This method applies (or modifies) the lookuptable for all types of images.
virtual BaseGeometry::Pointer GetGeometryForTimeStep(TimeStepType timeStep) const =0
Returns the geometry which corresponds to the given time step.
LabelSetImage class for handling labels and layers in a segmentation session.
virtual bool IsInitialized() const
Check whether the data has been initialized, i.e., at least the Geometry and other header data has be...
unsigned short PixelType
Definition: mitkLabel.h:40
const mitk::Color & GetColor() const
Definition: mitkLabel.cpp:199
std::vector< vtkSmartPointer< vtkNeverTranslucentTexture > > m_LayerTextureVector
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 ...
unsigned int GetActiveLayer() const
Gets the ID of the currently active layer.
virtual void UpdateOutputInformation() override
PixelType GetValue() const
Definition: mitkLabel.cpp:171
std::vector< mitk::ExtractSliceFilter::Pointer > m_ReslicerVector
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
std::vector< vtkSmartPointer< vtkPolyDataMapper > > m_LayerMapperVector
vtkSmartPointer< vtkPolyDataMapper > m_OutlineMapper
A mapper for the outline.
bool GetVisibility(bool &visible, const mitk::BaseRenderer *renderer, const char *propertyKey="visible") const
Convenience access method for visibility properties (instances of BoolProperty with property-key "vis...
Definition: mitkDataNode.h:413
mitk::LabelSet * GetLabelSet(unsigned int layer=0)
Gets the mitk::LabelSet for the given layer.
itk::TimeStamp m_LastDataUpdateTime
Timestamp of last update of stored data.
virtual bool IsValidTimeStep(TimeStepType timeStep) const =0
Test for the given time step if a geometry is availible.
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
vtkSmartPointer< vtkPolyData > CreateOutlinePolyData(mitk::BaseRenderer *renderer, vtkImageData *image, int pixelValue=1)
Generates a vtkPolyData object containing the outline of a given binary slice.
void GeneratePlane(mitk::BaseRenderer *renderer, double planeBounds[6])
Generates a plane according to the size of the resliced image in milimeters.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.