Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
vtkMitkGPUVolumeRayCastMapper.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 
18  Program: Visualization Toolkit
19  Module: $RCSfile: vtkMitkGPUVolumeRayCastMapper.cxx,v $
20 
21  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
22  All rights reserved.
23  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
24 
25  This software is distributed WITHOUT ANY WARRANTY; without even
26  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
27  PURPOSE. See the above copyright notice for more information.
28 
29 =========================================================================*/
30 
32 
33 // Only with VTK 5.6 or above
34 #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION == 5) && (VTK_MINOR_VERSION >= 6)))
35 
36 #include "vtkCamera.h"
37 #include "vtkCellData.h"
38 #include "vtkCommand.h" // for VolumeMapperRender{Start|End|Progress}Event
39 #include "vtkDataArray.h"
40 #include "vtkGPUInfo.h"
41 #include "vtkGPUInfoList.h"
42 #include "vtkImageData.h"
43 #include "vtkImageResample.h"
44 #include "vtkMultiThreader.h"
45 #include "vtkPointData.h"
46 #include "vtkRenderWindow.h"
47 #include "vtkRenderer.h"
48 #include "vtkRendererCollection.h"
49 #include "vtkTimerLog.h"
50 #include "vtkVolume.h"
51 #include "vtkVolumeProperty.h"
52 #include <assert.h>
53 
54 vtkInstantiatorNewMacro(vtkMitkGPUVolumeRayCastMapper);
55 vtkCxxSetObjectMacro(vtkMitkGPUVolumeRayCastMapper, MaskInput, vtkImageData);
56 vtkCxxSetObjectMacro(vtkMitkGPUVolumeRayCastMapper, TransformedInput, vtkImageData);
57 
58 vtkMitkGPUVolumeRayCastMapper::vtkMitkGPUVolumeRayCastMapper()
59 {
60  this->AutoAdjustSampleDistances = 1;
61  this->ImageSampleDistance = 1.0;
62  this->MinimumImageSampleDistance = 1.0;
63  this->MaximumImageSampleDistance = 10.0;
64  this->SampleDistance = 1.0;
65  this->SmallVolumeRender = 0;
66  this->BigTimeToDraw = 0.0;
67  this->SmallTimeToDraw = 0.0;
68  this->FinalColorWindow = 1.0;
69  this->FinalColorLevel = 0.5;
70  this->GeneratingCanonicalView = 0;
71  this->CanonicalViewImageData = nullptr;
72 
73  this->MaskInput = nullptr;
74  this->MaskBlendFactor = 1.0f;
75 
76  this->AMRMode = 0;
77  this->ClippedCroppingRegionPlanes[0] = VTK_DOUBLE_MAX;
78  this->ClippedCroppingRegionPlanes[1] = VTK_DOUBLE_MIN;
79  this->ClippedCroppingRegionPlanes[2] = VTK_DOUBLE_MAX;
80  this->ClippedCroppingRegionPlanes[3] = VTK_DOUBLE_MIN;
81  this->ClippedCroppingRegionPlanes[4] = VTK_DOUBLE_MAX;
82  this->ClippedCroppingRegionPlanes[5] = VTK_DOUBLE_MIN;
83 
84  this->MaxMemoryInBytes = 0;
85  vtkGPUInfoList *l = vtkGPUInfoList::New();
86  l->Probe();
87  if (l->GetNumberOfGPUs() > 0)
88  {
89  vtkGPUInfo *info = l->GetGPUInfo(0);
90  this->MaxMemoryInBytes = info->GetDedicatedVideoMemory();
91  if (this->MaxMemoryInBytes == 0)
92  {
93  this->MaxMemoryInBytes = info->GetDedicatedSystemMemory();
94  }
95  // we ignore info->GetSharedSystemMemory(); as this is very slow.
96  }
97  l->Delete();
98 
99  if (this->MaxMemoryInBytes == 0) // use some default value: 128MB.
100  {
101  this->MaxMemoryInBytes = 128 * 1024 * 1024;
102  }
103 
104  this->MaxMemoryFraction = 0.75;
105 
106  this->ReportProgress = true;
107 
108  this->TransformedInput = nullptr;
109  this->LastInput = nullptr;
110 }
111 
112 // ----------------------------------------------------------------------------
113 vtkMitkGPUVolumeRayCastMapper::~vtkMitkGPUVolumeRayCastMapper()
114 {
115  this->SetMaskInput(nullptr);
116  this->SetTransformedInput(nullptr);
117  this->LastInput = nullptr;
118 }
119 
120 // ----------------------------------------------------------------------------
121 // The render method that is called from the volume. If this is a canonical
122 // view render, a specialized version of this method will be called instead.
123 // Otherwise we will
124 // - Invoke a start event
125 // - Start timing
126 // - Check that everything is OK for rendering
127 // - Render
128 // - Stop the timer and record results
129 // - Invoke an end event
130 // ----------------------------------------------------------------------------
131 void vtkMitkGPUVolumeRayCastMapper::Render(vtkRenderer *ren, vtkVolume *vol)
132 {
133  // Catch renders that are happening due to a canonical view render and
134  // handle them separately.
135  if (this->GeneratingCanonicalView)
136  {
137  this->CanonicalViewRender(ren, vol);
138  return;
139  }
140 
141  // Invoke a VolumeMapperRenderStartEvent
142  this->InvokeEvent(vtkCommand::VolumeMapperRenderStartEvent, nullptr);
143 
144  // Start the timer to time the length of this render
145  vtkTimerLog *timer = vtkTimerLog::New();
146  timer->StartTimer();
147 
148  // Make sure everything about this render is OK.
149  // This is where the input is updated.
150  if (this->ValidateRender(ren, vol))
151  {
152  // Everything is OK - so go ahead and really do the render
153  this->GPURender(ren, vol);
154  }
155 
156  // Stop the timer
157  timer->StopTimer();
158  double t = timer->GetElapsedTime();
159 
160  // cout << "Render Timer " << t << " seconds, " << 1.0/t << " frames per second" << endl;
161 
162  this->TimeToDraw = t;
163  timer->Delete();
164 
165  if (vol->GetAllocatedRenderTime() < 1.0)
166  {
167  this->SmallTimeToDraw = t;
168  }
169  else
170  {
171  this->BigTimeToDraw = t;
172  }
173 
174  // Invoke a VolumeMapperRenderEndEvent
175  this->InvokeEvent(vtkCommand::VolumeMapperRenderEndEvent, nullptr);
176 }
177 
178 // ----------------------------------------------------------------------------
179 // Special version for rendering a canonical view - we don't do things like
180 // invoke start or end events, and we don't capture the render time.
181 // ----------------------------------------------------------------------------
182 void vtkMitkGPUVolumeRayCastMapper::CanonicalViewRender(vtkRenderer *ren, vtkVolume *vol)
183 {
184  // Make sure everything about this render is OK
185  if (this->ValidateRender(ren, vol))
186  {
187  // Everything is OK - so go ahead and really do the render
188  this->GPURender(ren, vol);
189  }
190 }
191 
192 // ----------------------------------------------------------------------------
193 // This method us used by the render method to validate everything before
194 // attempting to render. This method returns 0 if something is not right -
195 // such as missing input, a null renderer or a null volume, no scalars, etc.
196 // In some cases it will produce a vtkErrorMacro message, and in others
197 // (for example, in the case of cropping planes that define a region with
198 // a volume or 0 or less) it will fail silently. If everything is OK, it will
199 // return with a value of 1.
200 // ----------------------------------------------------------------------------
201 int vtkMitkGPUVolumeRayCastMapper::ValidateRender(vtkRenderer *ren, vtkVolume *vol)
202 {
203  // Check that we have everything we need to render.
204  int goodSoFar = 1;
205 
206  // Check for a renderer - we MUST have one
207  if (!ren)
208  {
209  goodSoFar = 0;
210  vtkErrorMacro("Renderer cannot be null.");
211  }
212 
213  // Check for the volume - we MUST have one
214  if (goodSoFar && !vol)
215  {
216  goodSoFar = 0;
217  vtkErrorMacro("Volume cannot be null.");
218  }
219 
220  // Don't need to check if we have a volume property
221  // since the volume will create one if we don't. Also
222  // don't need to check for the scalar opacity function
223  // or the RGB transfer function since the property will
224  // create them if they do not yet exist.
225 
226  // However we must currently check that the number of
227  // color channels is 3
228  // TODO: lift this restriction - should work with
229  // gray functions as well. Right now turning off test
230  // because otherwise 4 component rendering isn't working.
231  // Will revisit.
232  if (goodSoFar && vol->GetProperty()->GetColorChannels() != 3)
233  {
234  // goodSoFar = 0;
235  // vtkErrorMacro("Must have a color transfer function.");
236  }
237 
238  // Check the cropping planes. If they are invalid, just silently
239  // fail. This will happen when an interactive widget is dragged
240  // such that it defines 0 or negative volume - this can happen
241  // and should just not render the volume.
242  // Check the cropping planes
243  if (goodSoFar && this->Cropping && (this->CroppingRegionPlanes[0] >= this->CroppingRegionPlanes[1] ||
244  this->CroppingRegionPlanes[2] >= this->CroppingRegionPlanes[3] ||
245  this->CroppingRegionPlanes[4] >= this->CroppingRegionPlanes[5]))
246  {
247  // No error message here - we want to be silent
248  goodSoFar = 0;
249  }
250 
251  // Check that we have input data
252  vtkImageData *input = this->GetInput();
253 
254  // If we have a timestamp change or data change then create a new clone.
255  if (input != this->LastInput || input->GetMTime() > this->TransformedInput->GetMTime())
256  {
257  this->LastInput = input;
258 
259  vtkImageData *clone;
260  if (!this->TransformedInput)
261  {
262  clone = vtkImageData::New();
263  this->SetTransformedInput(clone);
264  clone->Delete();
265  }
266  else
267  {
268  clone = this->TransformedInput;
269  }
270 
271  clone->ShallowCopy(input);
272 
273  // @TODO: This is the workaround to deal with GPUVolumeRayCastMapper
274  // not able to handle extents starting from non zero values.
275  // There is not a easy fix in the GPU volume ray cast mapper hence
276  // this fix has been introduced.
277 
278  // Get the current extents.
279  int extents[6], real_extents[6];
280  clone->GetExtent(extents);
281  clone->GetExtent(real_extents);
282 
283  // Get the current origin and spacing.
284  double origin[3], spacing[3];
285  clone->GetOrigin(origin);
286  clone->GetSpacing(spacing);
287 
288  for (int cc = 0; cc < 3; cc++)
289  {
290  // Transform the origin and the extents.
291  origin[cc] = origin[cc] + extents[2 * cc] * spacing[cc];
292  extents[2 * cc + 1] -= extents[2 * cc];
293  extents[2 * cc] -= extents[2 * cc];
294  }
295 
296  clone->SetOrigin(origin);
297  clone->SetExtent(extents);
298  }
299 
300  if (goodSoFar && !this->TransformedInput)
301  {
302  vtkErrorMacro("Input is NULL but is required");
303  goodSoFar = 0;
304  }
305 
306  // Update the date then make sure we have scalars. Note
307  // that we must have point or cell scalars because field
308  // scalars are not supported.
309  vtkDataArray *scalars = nullptr;
310  if (goodSoFar)
311  {
312  // Here is where we update the input
313  // this->TransformedInput->UpdateInformation(); //VTK6_TODO
314  // this->TransformedInput->SetUpdateExtentToWholeExtent();
315  // this->TransformedInput->Update();
316 
317  // Now make sure we can find scalars
318  scalars = this->GetScalars(
319  this->TransformedInput, this->ScalarMode, this->ArrayAccessMode, this->ArrayId, this->ArrayName, this->CellFlag);
320 
321  // We couldn't find scalars
322  if (!scalars)
323  {
324  vtkErrorMacro("No scalars found on input.");
325  goodSoFar = 0;
326  }
327  // Even if we found scalars, if they are field data scalars that isn't good
328  else if (this->CellFlag == 2)
329  {
330  vtkErrorMacro("Only point or cell scalar support - found field scalars instead.");
331  goodSoFar = 0;
332  }
333  }
334 
335  // Make sure the scalar type is actually supported. This mappers supports
336  // almost all standard scalar types.
337  if (goodSoFar)
338  {
339  switch (scalars->GetDataType())
340  {
341  case VTK_CHAR:
342  vtkErrorMacro(<< "scalar of type VTK_CHAR is not supported "
343  << "because this type is platform dependent. "
344  << "Use VTK_SIGNED_CHAR or VTK_UNSIGNED_CHAR instead.");
345  goodSoFar = 0;
346  break;
347  case VTK_BIT:
348  vtkErrorMacro("scalar of type VTK_BIT is not supported by this mapper.");
349  goodSoFar = 0;
350  break;
351  case VTK_ID_TYPE:
352  vtkErrorMacro("scalar of type VTK_ID_TYPE is not supported by this mapper.");
353  goodSoFar = 0;
354  break;
355  case VTK_STRING:
356  vtkErrorMacro("scalar of type VTK_STRING is not supported by this mapper.");
357  goodSoFar = 0;
358  break;
359  default:
360  // Don't need to do anything here
361  break;
362  }
363  }
364 
365  // Check on the blending type - we support composite and min / max intensity
366  if (goodSoFar)
367  {
368  if (this->BlendMode != vtkVolumeMapper::COMPOSITE_BLEND &&
369  this->BlendMode != vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND &&
370  this->BlendMode != vtkVolumeMapper::MINIMUM_INTENSITY_BLEND)
371  {
372  goodSoFar = 0;
373  vtkErrorMacro(<< "Selected blend mode not supported. "
374  << "Only Composite and MIP and MinIP modes "
375  << "are supported by the current implementation.");
376  }
377  }
378 
379  // This mapper supports 1 component data, or 4 component if it is not independent
380  // component (i.e. the four components define RGBA)
381  int numberOfComponents = 0;
382  if (goodSoFar)
383  {
384  numberOfComponents = scalars->GetNumberOfComponents();
385  if (!(numberOfComponents == 1 || (numberOfComponents == 4 && vol->GetProperty()->GetIndependentComponents() == 0)))
386  {
387  goodSoFar = 0;
388  vtkErrorMacro(<< "Only one component scalars, or four "
389  << "component with non-independent components, "
390  << "are supported by this mapper.");
391  }
392  }
393 
394  // If this is four component data, then it better be unsigned char (RGBA).
395  if (goodSoFar && numberOfComponents == 4 && scalars->GetDataType() != VTK_UNSIGNED_CHAR)
396  {
397  goodSoFar = 0;
398  vtkErrorMacro("Only unsigned char is supported for 4-component scalars!");
399  }
400 
401  // return our status
402  return goodSoFar;
403 }
404 
405 // ----------------------------------------------------------------------------
406 // Description:
407 // Called by the AMR Volume Mapper.
408 // Set the flag that tells if the scalars are on point data (0) or
409 // cell data (1).
410 void vtkMitkGPUVolumeRayCastMapper::SetCellFlag(int cellFlag)
411 {
412  this->CellFlag = cellFlag;
413 }
414 
415 // ----------------------------------------------------------------------------
416 void vtkMitkGPUVolumeRayCastMapper::CreateCanonicalView(vtkRenderer *ren,
417  vtkVolume *volume,
418  vtkImageData *image,
419  int vtkNotUsed(blend_mode),
420  double viewDirection[3],
421  double viewUp[3])
422 {
423  this->GeneratingCanonicalView = 1;
424  int oldSwap = ren->GetRenderWindow()->GetSwapBuffers();
425  ren->GetRenderWindow()->SwapBuffersOff();
426 
427  int dim[3];
428  image->GetDimensions(dim);
429  int *size = ren->GetRenderWindow()->GetSize();
430 
431  vtkImageData *bigImage = vtkImageData::New();
432  bigImage->SetDimensions(size[0], size[1], 1);
433  bigImage->AllocateScalars(VTK_UNSIGNED_CHAR, 3);
434 
435  this->CanonicalViewImageData = bigImage;
436 
437  double scale[2];
438  scale[0] = dim[0] / static_cast<double>(size[0]);
439  scale[1] = dim[1] / static_cast<double>(size[1]);
440 
441  // Save the visibility flags of the renderers and set all to false except
442  // for the ren.
443  vtkRendererCollection *renderers = ren->GetRenderWindow()->GetRenderers();
444  int numberOfRenderers = renderers->GetNumberOfItems();
445 
446  auto rendererVisibilities = new bool[numberOfRenderers];
447  renderers->InitTraversal();
448  int i = 0;
449  while (i < numberOfRenderers)
450  {
451  vtkRenderer *r = renderers->GetNextItem();
452  rendererVisibilities[i] = r->GetDraw() == 1;
453  if (r != ren)
454  {
455  r->SetDraw(false);
456  }
457  ++i;
458  }
459 
460  // Save the visibility flags of the props and set all to false except
461  // for the volume.
462 
463  vtkPropCollection *props = ren->GetViewProps();
464  int numberOfProps = props->GetNumberOfItems();
465 
466  auto propVisibilities = new bool[numberOfProps];
467  props->InitTraversal();
468  i = 0;
469  while (i < numberOfProps)
470  {
471  vtkProp *p = props->GetNextProp();
472  propVisibilities[i] = p->GetVisibility() == 1;
473  if (p != volume)
474  {
475  p->SetVisibility(false);
476  }
477  ++i;
478  }
479 
480  vtkCamera *savedCamera = ren->GetActiveCamera();
481  savedCamera->Modified();
482  vtkCamera *canonicalViewCamera = vtkCamera::New();
483 
484  // Code from vtkFixedPointVolumeRayCastMapper:
485  double *center = volume->GetCenter();
486  double bounds[6];
487  volume->GetBounds(bounds);
488  double d =
489  sqrt((bounds[1] - bounds[0]) * (bounds[1] - bounds[0]) + (bounds[3] - bounds[2]) * (bounds[3] - bounds[2]) +
490  (bounds[5] - bounds[4]) * (bounds[5] - bounds[4]));
491 
492  // For now use x distance - need to change this
493  d = bounds[1] - bounds[0];
494 
495  // Set up the camera in parallel
496  canonicalViewCamera->SetFocalPoint(center);
497  canonicalViewCamera->ParallelProjectionOn();
498  canonicalViewCamera->SetPosition(
499  center[0] - d * viewDirection[0], center[1] - d * viewDirection[1], center[2] - d * viewDirection[2]);
500  canonicalViewCamera->SetViewUp(viewUp);
501  canonicalViewCamera->SetParallelScale(d / 2);
502 
503  ren->SetActiveCamera(canonicalViewCamera);
504  ren->GetRenderWindow()->Render();
505 
506  ren->SetActiveCamera(savedCamera);
507  canonicalViewCamera->Delete();
508 
509  // Shrink to image to the desired size
510  vtkImageResample *resample = vtkImageResample::New();
511  resample->SetInputData(bigImage);
512  resample->SetAxisMagnificationFactor(0, scale[0]);
513  resample->SetAxisMagnificationFactor(1, scale[1]);
514  resample->SetAxisMagnificationFactor(2, 1);
515  resample->UpdateWholeExtent();
516 
517  // Copy the pixels over
518  image->DeepCopy(resample->GetOutput());
519 
520  bigImage->Delete();
521  resample->Delete();
522 
523  // Restore the visibility flags of the props
524  props->InitTraversal();
525  i = 0;
526  while (i < numberOfProps)
527  {
528  vtkProp *p = props->GetNextProp();
529  p->SetVisibility(propVisibilities[i]);
530  ++i;
531  }
532 
533  delete[] propVisibilities;
534 
535  // Restore the visibility flags of the renderers
536  renderers->InitTraversal();
537  i = 0;
538  while (i < numberOfRenderers)
539  {
540  vtkRenderer *r = renderers->GetNextItem();
541  r->SetDraw(rendererVisibilities[i]);
542  ++i;
543  }
544 
545  delete[] rendererVisibilities;
546 
547  ren->GetRenderWindow()->SetSwapBuffers(oldSwap);
548  this->CanonicalViewImageData = nullptr;
549  this->GeneratingCanonicalView = 0;
550 }
551 
552 // ----------------------------------------------------------------------------
553 // Print method for vtkMitkGPUVolumeRayCastMapper
554 void vtkMitkGPUVolumeRayCastMapper::PrintSelf(ostream &os, vtkIndent indent)
555 {
556  this->Superclass::PrintSelf(os, indent);
557 
558  os << indent << "AutoAdjustSampleDistances: " << this->AutoAdjustSampleDistances << endl;
559  os << indent << "MinimumImageSampleDistance: " << this->MinimumImageSampleDistance << endl;
560  os << indent << "MaximumImageSampleDistance: " << this->MaximumImageSampleDistance << endl;
561  os << indent << "ImageSampleDistance: " << this->ImageSampleDistance << endl;
562  os << indent << "SampleDistance: " << this->SampleDistance << endl;
563  os << indent << "FinalColorWindow: " << this->FinalColorWindow << endl;
564  os << indent << "FinalColorLevel: " << this->FinalColorLevel << endl;
565  os << indent << "MaskInput: " << this->MaskInput << endl;
566  os << indent << "MaskBlendFactor: " << this->MaskBlendFactor << endl;
567  os << indent << "MaxMemoryInBytes: " << this->MaxMemoryInBytes << endl;
568  os << indent << "MaxMemoryFraction: " << this->MaxMemoryFraction << endl;
569  os << indent << "ReportProgress: " << this->ReportProgress << endl;
570 }
571 
572 // ----------------------------------------------------------------------------
573 // Description:
574 // Compute the cropping planes clipped by the bounds of the volume.
575 // The result is put into this->ClippedCroppingRegionPlanes.
576 // NOTE: IT WILL BE MOVED UP TO vtkVolumeMapper after bullet proof usage
577 // in this mapper. Other subclasses will use the ClippedCroppingRegionsPlanes
578 // members instead of CroppingRegionPlanes.
579 // \pre volume_exists: this->GetInput()!=0
580 // \pre valid_cropping: this->Cropping &&
581 // this->CroppingRegionPlanes[0]<this->CroppingRegionPlanes[1] &&
582 // this->CroppingRegionPlanes[2]<this->CroppingRegionPlanes[3] &&
583 // this->CroppingRegionPlanes[4]<this->CroppingRegionPlanes[5])
584 void vtkMitkGPUVolumeRayCastMapper::ClipCroppingRegionPlanes()
585 {
586  assert("pre: volume_exists" && this->GetInput() != nullptr);
587  assert("pre: valid_cropping" && this->Cropping && this->CroppingRegionPlanes[0] < this->CroppingRegionPlanes[1] &&
588  this->CroppingRegionPlanes[2] < this->CroppingRegionPlanes[3] &&
589  this->CroppingRegionPlanes[4] < this->CroppingRegionPlanes[5]);
590 
591  // vtkVolumeMapper::Render() will have something like:
592  // if(this->Cropping && (this->CroppingRegionPlanes[0]>=this->CroppingRegionPlanes[1] ||
593  // this->CroppingRegionPlanes[2]>=this->CroppingRegionPlanes[3] ||
594  // this->CroppingRegionPlanes[4]>=this->CroppingRegionPlanes[5]))
595  // {
596  // // silentely stop because the cropping is not valid.
597  // return;
598  // }
599 
600  double volBounds[6];
601  this->GetInput()->GetBounds(volBounds);
602 
603  int i = 0;
604  while (i < 6)
605  {
606  // max of the mins
607  if (this->CroppingRegionPlanes[i] < volBounds[i])
608  {
609  this->ClippedCroppingRegionPlanes[i] = volBounds[i];
610  }
611  else
612  {
613  this->ClippedCroppingRegionPlanes[i] = this->CroppingRegionPlanes[i];
614  }
615  ++i;
616  // min of the maxs
617  if (this->CroppingRegionPlanes[i] > volBounds[i])
618  {
619  this->ClippedCroppingRegionPlanes[i] = volBounds[i];
620  }
621  else
622  {
623  this->ClippedCroppingRegionPlanes[i] = this->CroppingRegionPlanes[i];
624  }
625  ++i;
626  }
627 }
628 
629 #endif
static void info(const char *fmt,...)
Definition: svm.cpp:100
vtkInstantiatorNewMacro(vtkMitkVolumeTextureMapper3D)
static void clone(T *&dst, S *src, int n)
Definition: svm.cpp:73
vtkCxxSetObjectMacro(vtkXMLMaterialParser, Material, vtkXMLMaterial)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.