Introduction
Recently, I was required to work with VTK, an interesting (and powerful) library for visualization. I have found a lack of documentation regarding using VTK in MFC, so, I decided to write a small guide for those who want to use VTK in MFC.
Background
In my case, I have used Visual Studio 2008 and VTK 6.1. I have tried to compile VTK 6.1 with VC6, but it didn't work :).
Necessary Steps
Step 1
First of all, you just need to download the source of library and data. And put them somewhere on your HDD. For example, let's chose C: partition. So, we have two folders: C:\VTK\VTK-6.1.0 and C:\VTK\VTKData-6.1.0.
Step 2
You need to download CMake
from here. Unzip the file, and start cmake-gui.exe. You will have something like:
On the code source edit box, type C:/VTK/VTK-6.1.0 and on binaries edit box, type C:/VTK/bin ... there, the CMake
will create a bin folder inside of C:\VTK\. Push Configure button. The CMake
will popup the following window:
Just push Finish button, and wait ... when the CMake
is finished the job, it will give you a message Configuring done and in the output list some red lines ...
Step 3
Inside of C:\VTK\bin folder, you must have CMakeCache.txt file. Open it and edit the following lines:
BUILD_EXAMPLES:BOOL=ON
into:
BUILD_EXAMPLES:BOOL=OFF
and:
Module_vtkGUISupportMFC:BOOL=OFF
into:
Module_vtkGUISupportMFC:BOOL=ON
Save the file, and go back to cmake-gui.exe
.
Step 4
No press again Configure button. You will get the same message: Configuring done. And after that, press Generate button in order to generate solution file by Visual Studio 2008 compiler.
Step 5
Open VTK.sln solution file from C:\VTK\Bin\ installed folder. And compile and build ALL_BUILD
project ... this task will take a long time ... And after building has ended, build Install
project, in order to install VTK in C:\Program Files\ folder. Now you are ready to go! In order to use VTK inside of MFC project, you just need to include VTK headers and VTK library files, just like in TestBMP
testing project attached. The headers are in C++->Additional Include Directories, and library files are in Linker->Input->Additional Dependencies. One more thing, in stdafx.h file, you will have to add:
#define vtkRenderingCore_AUTOINIT 4
(vtkInteractionStyle,vtkRenderingFreeType,vtkRenderingFreeTypeOpenGL,vtkRenderingOpenGL)
#define vtkRenderingVolume_AUTOINIT 1(vtkRenderingVolumeOpenGL)
Using the Code
Let's consider that we have to read bitmap files. For that, we have to include inside of CDocument
header:
#include "vtkBMPReader.h"
class CTestBMPDoc : public CDocument
{
protected: CTestBMPDoc();
DECLARE_DYNCREATE(CTestBMPDoc)
public:
vtkBMPReader* m_pvtkBMPReader;
.......
}
and in implementation file:
CTestBMPDoc::CTestBMPDoc()
{
m_pvtkBMPReader = NULL;
}
void CTestBMPDoc::OnCloseDocument()
{
if(NULL != m_pvtkBMPReader)
m_pvtkBMPReader->Delete();
CDocument::OnCloseDocument();
}
BOOL CTestBMPDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (! CDocument::OnOpenDocument(lpszPathName))
return FALSE;
m_pvtkBMPReader = vtkBMPReader::New();
m_pvtkBMPReader->SetFileName(lpszPathName);
return TRUE;
}
and to render bitmap files inside of CView
class, we have to use some VTK objects: vtkMFCWindow
, vtkRenderer
, vtkImageActor
. An example of using these objects in CView
:
#include "vtkMFCWindow.h"
#include "vtkRenderer.h"
#include "vtkImageActor.h"
class CTestBMPView : public CView
{
protected: CTestBMPView();
DECLARE_DYNCREATE(CTestBMPView)
public:
CTestBMPDoc* GetDocument() const;
public:
protected:
vtkMFCWindow* m_pvtkMFCWindow;
vtkRenderer* m_pvtkRenderer;
vtkImageActor* m_pvtkImageActor;
...
}
and in implementation CView
file:
CTestBMPView::CTestBMPView()
{
m_pvtkMFCWindow = NULL;
m_pvtkRenderer = vtkRenderer::New();
m_pvtkImageActor = vtkImageActor::New();
}
CTestBMPView::~CTestBMPView()
{
if(NULL != m_pvtkMFCWindow)
delete m_pvtkMFCWindow;
}
void CTestBMPView::OnDestroy()
{
if(NULL != m_pvtkRenderer)
m_pvtkRenderer->Delete();
if(NULL != m_pvtkImageActor)
m_pvtkImageActor->Delete();
CView::OnDestroy();
}
BOOL CTestBMPView::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CTestBMPView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
if(NULL != m_pvtkMFCWindow)
m_pvtkMFCWindow->MoveWindow(0, 0, cx, cy);
}
void CTestBMPView::OnInitialUpdate()
{
CView::OnInitialUpdate();
m_pvtkMFCWindow = new vtkMFCWindow(this);
m_pvtkMFCWindow->GetRenderWindow()->AddRenderer(m_pvtkRenderer);
m_pvtkRenderer->SetBackground(0.0, 0.0, 0.5);
if(NULL != GetDocument()->m_pvtkBMPReader)
{
m_pvtkImageActor->GetMapper()->SetInputConnection(GetDocument()->m_pvtkBMPReader->GetOutputPort());
m_pvtkRenderer->AddActor(m_pvtkImageActor);
}
}
You will find more details inside the sample project. Enjoy it!