Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkRenderingTestHelper.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 // VTK
18 #include <vtkCamera.h>
19 #include <vtkPNGWriter.h>
20 #include <vtkRenderLargeImage.h>
21 #include <vtkRenderWindow.h>
22 #include <vtkRenderWindowInteractor.h>
23 
24 // MITK
26 #include <mitkRenderWindow.h>
30 
31 // include gl to read out properties
32 #include <vtkOpenGL.h>
33 #include <vtkOpenGLExtensionManager.h>
34 #include <vtksys/SystemTools.hxx>
35 
36 #if defined _MSC_VER
37 #if _MSC_VER >= 1700
38 #define RESIZE_WORKAROUND
39 #endif
40 #endif
41 
42 #ifdef RESIZE_WORKAROUND
43 #include "vtkWin32OpenGLRenderWindow.h"
44 #endif
45 
46 // VTK Testing to compare the rendered image pixel-wise against a reference screen shot
47 #include "vtkTesting.h"
48 
50  int height,
52  : m_AutomaticallyCloseRenderWindow(true)
53 {
54  this->Initialize(width, height, renderingMode);
55 }
56 
58  int width, int height, int argc, char *argv[], mitk::BaseRenderer::RenderingMode::Type renderingMode)
59  : m_AutomaticallyCloseRenderWindow(true)
60 {
61  this->Initialize(width, height, renderingMode);
62  this->SetInputFileNames(argc, argv);
63 }
64 
66 {
67  m_RenderWindow = mitk::RenderWindow::New(NULL, "unnamed renderer", NULL, renderingMode);
68 
70 
71  m_RenderWindow->GetRenderer()->SetDataStorage(m_DataStorage);
72  this->SetMapperIDToRender2D();
73  this->GetVtkRenderWindow()->SetSize(width, height);
74 
75 #ifdef RESIZE_WORKAROUND
76 
77  HWND hWnd = static_cast<vtkWin32OpenGLRenderWindow *>(this->GetVtkRenderWindow())->GetWindowId();
78 
79  RECT r;
80  r.left = 10;
81  r.top = 10;
82  r.right = r.left + width;
83  r.bottom = r.top + height;
84 
85  LONG style = GetWindowLong(hWnd, GWL_STYLE);
86  AdjustWindowRect(&r, style, FALSE);
87 
88  MITK_INFO << "WANTED:";
89  MITK_INFO << r.right - r.left;
90  MITK_INFO << r.bottom - r.top;
91 
92  RECT rect;
93  if (GetWindowRect(hWnd, &rect))
94  {
95  int width = rect.right - rect.left;
96  int height = rect.bottom - rect.top;
97 
98  MITK_INFO << "ACTUAL:";
99  MITK_INFO << width;
100  MITK_INFO << height;
101  }
102 
103  SetWindowPos(hWnd, HWND_TOP, 0, 0, r.right - r.left, r.bottom - r.top, SWP_NOZORDER);
104 
105  GetWindowRect(hWnd, &rect);
106 
107  int width2 = rect.right - rect.left;
108  int height2 = rect.bottom - rect.top;
109 
110  MITK_INFO << "ACTUAL2:";
111  MITK_INFO << width2;
112  MITK_INFO << height2;
113 
114  SetWindowPos(hWnd, HWND_TOP, 0, 0, 2 * (r.right - r.left) - width2, 2 * (r.bottom - r.top) - height2, SWP_NOZORDER);
115 
116 #endif
117 
118  m_RenderWindow->GetRenderer()->Resize(width, height);
119 
120  // Prints the glinfo after creation of the vtkrenderwindow, we always want to do this for debugging.
121  this->PrintGLInfo();
122 }
123 
125 {
126 }
127 
129 {
130  const GLubyte *version = glGetString(GL_VERSION);
131  if (!version)
132  return false;
133  return *version >= '2';
134 }
135 
137 {
138  GLint maxTextureSize;
139 
140  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
141  ;
142 
143  MITK_INFO << "OpenGL Render Context Information: \n"
144  << "- GL_VENDOR: " << glGetString(GL_VENDOR) << "\n"
145  << "- GL_RENDERER: " << glGetString(GL_RENDERER) << "\n"
146  << "- GL_VERSION: " << glGetString(GL_VERSION) << "\n"
147  << "- GL_MAX_TEXTURE_SIZE: " << maxTextureSize << "\n"
148  << "- GL_EXTENSIONS: " << glGetString(GL_EXTENSIONS);
149 }
150 
152 {
153  m_RenderWindow->GetRenderer()->SetMapperID(id);
154 }
155 
157 {
158  this->SetMapperID(mitk::BaseRenderer::Standard3D);
160  this->GetDataStorage()->ComputeBoundingGeometry3D(this->GetDataStorage()->GetAll()));
161 }
162 
164 {
165  this->SetMapperID(mitk::BaseRenderer::Standard2D);
166 }
167 
169 {
170  // if the datastorage is initialized and at least 1 image is loaded render it
171  if (m_DataStorage.IsNotNull() || m_DataStorage->GetAll()->Size() >= 1)
172  {
173  // Prepare the VTK camera before rendering.
174  m_RenderWindow->GetRenderer()->PrepareRender();
175 
176  this->GetVtkRenderWindow()->Render();
177  this->GetVtkRenderWindow()->WaitForCompletion();
178  if (m_AutomaticallyCloseRenderWindow == false)
179  {
180  // Use interaction to stop the test
181  this->GetVtkRenderWindow()->GetInteractor()->Start();
182  }
183  }
184  else
185  {
186  MITK_ERROR << "No images loaded in data storage!";
187  }
188 }
189 
191 {
192  return m_DataStorage;
193 }
194 
196 {
197  // i is set 1, because 0 is the testname as string
198  // parse parameters
199  for (int i = 1; i < argc; ++i)
200  {
201  // add everything to a list but -T and -V
202  std::string tmp = argv[i];
203  if ((tmp.compare("-T")) && (tmp.compare("-V")))
204  {
205  this->AddToStorage(tmp);
206  }
207  else
208  {
209  break;
210  }
211  }
212 }
213 
215 {
216  mitk::BaseRenderer::GetInstance(m_RenderWindow->GetVtkRenderWindow())
217  ->GetSliceNavigationController()
218  ->SetDefaultViewDirection(viewDirection);
220  m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll()));
221 }
222 
224 {
225  mitk::SliceNavigationController::Pointer sliceNavigationController =
226  mitk::BaseRenderer::GetInstance(m_RenderWindow->GetVtkRenderWindow())->GetSliceNavigationController();
227  sliceNavigationController->ReorientSlices(origin, rotation);
228 }
229 
231 {
232  return m_RenderWindow->GetRenderer()->GetVtkRenderer();
233 }
234 
235 void mitk::RenderingTestHelper::SetImageProperty(const char *propertyKey, mitk::BaseProperty *property)
236 {
237  this->m_DataStorage->GetNode(mitk::NodePredicateDataType::New("Image"))->SetProperty(propertyKey, property);
238 }
239 
241 {
242  return m_RenderWindow->GetVtkRenderWindow();
243 }
244 
245 bool mitk::RenderingTestHelper::CompareRenderWindowAgainstReference(int argc, char *argv[], double threshold)
246 {
247  this->Render();
248  // retVal meanings: (see VTK/Rendering/vtkTesting.h)
249  // 0 = test failed
250  // 1 = test passed
251  // 2 = test not run
252  // 3 = something with vtkInteraction
253  if (vtkTesting::Test(argc, argv, this->GetVtkRenderWindow(), threshold) == 1)
254  return true;
255  else
256  return false;
257 }
258 
259 // method to save a screenshot of the renderwindow (e.g. create a reference screenshot)
260 void mitk::RenderingTestHelper::SaveAsPNG(std::string fileName)
261 {
262  vtkSmartPointer<vtkRenderer> renderer = this->GetVtkRenderer();
263  bool doubleBuffering(renderer->GetRenderWindow()->GetDoubleBuffer());
264  renderer->GetRenderWindow()->DoubleBufferOff();
265 
266  vtkSmartPointer<vtkRenderLargeImage> magnifier = vtkSmartPointer<vtkRenderLargeImage>::New();
267  magnifier->SetInput(renderer);
268  magnifier->SetMagnification(1);
269 
270  vtkSmartPointer<vtkImageWriter> fileWriter = vtkSmartPointer<vtkPNGWriter>::New();
271  fileWriter->SetInputConnection(magnifier->GetOutputPort());
272  fileWriter->SetFileName(fileName.c_str());
273 
274  fileWriter->Write();
275  renderer->GetRenderWindow()->SetDoubleBuffer(doubleBuffering);
276 }
277 
278 void mitk::RenderingTestHelper::SetAutomaticallyCloseRenderWindow(bool automaticallyCloseRenderWindow)
279 {
280  m_AutomaticallyCloseRenderWindow = automaticallyCloseRenderWindow;
281 }
282 
284 {
285  this->SaveAsPNG(fileName);
286 }
287 
289 {
290  try
291  {
292  mitk::IOUtil::Load(filename, *m_DataStorage.GetPointer());
294  m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll()));
295  }
296  catch (itk::ExceptionObject &e)
297  {
298  MITK_ERROR << "Failed loading test data '" << filename << "': " << e.what();
299  }
300 }
301 
303 {
304  this->m_DataStorage->Add(node);
306  m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll()));
307 }
void SaveAsPNG(std::string fileName)
Method can be used to save a screenshot (e.g. reference screenshot as a .png file.
virtual bool InitializeViews(const BaseGeometry *geometry, RequestType type=REQUEST_UPDATE_ALL, bool preserveRoughOrientationInWorldSpace=false)
void SetViewDirection(mitk::SliceNavigationController::ViewDirection viewDirection)
Set the view direction of the renderwindow (e.g. sagittal, coronal, axial)
RenderingTestHelper(int width, int height, int argc, char *argv[], mitk::BaseRenderer::RenderingMode::Type renderingMode=mitk::BaseRenderer::RenderingMode::Standard)
Generate a rendering test helper object including a render window of the size width * height (in pixe...
static BaseRenderer * GetInstance(vtkRenderWindow *renWin)
#define MITK_INFO
Definition: mitkLogMacros.h:22
vtkRenderWindow * GetVtkRenderWindow()
Getter for the vtkRenderWindow which should be used to call vtkRegressionTestImage.
#define MITK_ERROR
Definition: mitkLogMacros.h:24
void SetMapperID(mitk::BaseRenderer::StandardMapperSlot id)
SetMapperID Change between Standard2D and 3D mappers.
bool IsAdvancedOpenGL()
Returns true if the opengl context is compatible for advanced vtk effects.
static mitk::DataStorage::Pointer GetDataStorage()
void SetMapperIDToRender3D()
SetMapperIDToRender3D Convenience method to render in a 3D renderwindow.
static Matrix3D rotation
void SaveReferenceScreenShot(std::string fileName)
SaveReferenceScreenShot Convenience method to save a reference screen shot.
static Pointer New()
void SetInputFileNames(int argc, char *argv[])
This method tries to parse the given argv for files (e.g. images) and load them into a member datasto...
bool CompareRenderWindowAgainstReference(int argc, char *argv[], double threshold=10.0)
CompareRenderWindowAgainstReference Convenience method to compare the image rendered in the internal ...
void SetImageProperty(const char *propertyKey, mitk::BaseProperty *property)
This method set the property of the member datastorage.
void ReorientSlices(mitk::Point3D origin, mitk::Vector3D rotation)
Reorient the slice (e.g. rotation and translation like the swivel mode).
Abstract base class for properties.
mitk::DataStorage::Pointer m_DataStorage
void Render()
Render everything into an mitkRenderWindow. Call SetViewDirection() and SetProperty() before this met...
static RenderingManager * GetInstance()
static const std::string filename
void AddToStorage(const std::string &filename)
This method tries to load the given file into a member datastorage, in order to render it...
mitk::DataStorage::Pointer GetDataStorage()
Returns the datastorage, in order to modify the data inside a rendering test.
static Pointer New(const char *_arg)
void Initialize(int width, int height, mitk::BaseRenderer::RenderingMode::Type renderingMode=mitk::BaseRenderer::RenderingMode::Standard)
Initialize Internal method to initialize the renderwindow and set the datastorage.
vtkRenderer * GetVtkRenderer()
Getter for the vtkRenderer.
void SetAutomaticallyCloseRenderWindow(bool automaticallyCloseRenderWindow)
SetStopRenderWindow Convenience method to make the renderwindow hold after rendering. Usefull for debugging.
void SetMapperIDToRender2D()
SetMapperIDToRender2D Convenience method to render in a 2D renderwindow.
void PrintGLInfo()
Prints the opengl information, e.g. version, vendor and extensions, This function can only be called ...
static DataStorage::SetOfObjects::Pointer Load(const std::string &path, DataStorage &storage)
Load a file into the given DataStorage.
Definition: mitkIOUtil.cpp:483
void AddNodeToStorage(mitk::DataNode::Pointer node)
AddNodeToStorage Add a node to the datastorage and perform a reinit which is necessary for rendering...
ViewDirection
Possible view directions, Original will uses the PlaneGeometry instances in a SlicedGeometry3D provid...
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.