Click here to Skip to main content
15,884,176 members
Articles / Web Development / HTML
Tip/Trick

VTK in MFC

Rate me:
Please Sign up or sign in to vote.
5.00/5 (10 votes)
10 Jul 2014CPOL2 min read 52.1K   1.9K   18   21
A small guide to use VTK in MFC

Sample Image - maximum width is 600 pixels

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 :).

Also, you can find here an reference about how to configure and build VTK library: http://www.vtk.org/Wiki/VTK/Configure_and_Build.

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:

Image 2

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:

Image 3

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 ...

Image 4

Step 3

Inside of C:\VTK\bin folder, you must have CMakeCache.txt file. Open it and edit the following lines:

C++
//Build VTK examples.
BUILD_EXAMPLES:BOOL=ON

into:

C++
//Build VTK examples.
BUILD_EXAMPLES:BOOL=OFF

and:

C++
//Request building vtkGUISupportMFC
Module_vtkGUISupportMFC:BOOL=OFF

into:

C++
//Request building vtkGUISupportMFC
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:

C++
#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:

C++
#include "vtkBMPReader.h"

class CTestBMPDoc : public CDocument
{
protected: // create from serialization only
    CTestBMPDoc();
    DECLARE_DYNCREATE(CTestBMPDoc)

// Attributes
public:
    vtkBMPReader* m_pvtkBMPReader;
.......
}

and in implementation file:

C++
CTestBMPDoc::CTestBMPDoc()
{
    // TODO: add one-time construction code here

    m_pvtkBMPReader = NULL;
}

void CTestBMPDoc::OnCloseDocument()
{
    // TODO: Add your specialized code here and/or call the base class

    if(NULL != m_pvtkBMPReader)
        m_pvtkBMPReader->Delete();

    CDocument::OnCloseDocument();
}

BOOL CTestBMPDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
    if (! CDocument::OnOpenDocument(lpszPathName))
        return FALSE;

    // TODO:  Add your specialized creation code here

    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:

C++
#include "vtkMFCWindow.h"
#include "vtkRenderer.h"
#include "vtkImageActor.h"

class CTestBMPView : public CView
{
protected: // create from serialization only
    CTestBMPView();
    DECLARE_DYNCREATE(CTestBMPView)

// Attributes
public:
    CTestBMPDoc* GetDocument() const;

// Operations
public:

protected:
    vtkMFCWindow* m_pvtkMFCWindow;
    vtkRenderer* m_pvtkRenderer;
    vtkImageActor* m_pvtkImageActor;
...
}

and in implementation CView file:

C++
CTestBMPView::CTestBMPView()
{
    // TODO: add construction code here

    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();

    // TODO: Add your message handler code here
}

BOOL CTestBMPView::OnEraseBkgnd(CDC* pDC)
{
    // TODO: Add your message handler code here and/or call default

    return TRUE;
//    return CView::OnEraseBkgnd(pDC);
}

void CTestBMPView::OnSize(UINT nType, int cx, int cy)
{
    CView::OnSize(nType, cx, cy);

    // TODO: Add your message handler code here

    if(NULL != m_pvtkMFCWindow)
        m_pvtkMFCWindow->MoveWindow(0, 0, cx, cy);
}

void CTestBMPView::OnInitialUpdate()
{
    CView::OnInitialUpdate();

    // TODO: Add your specialized code here and/or call the base class

    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)
    {
        //setup renderer
        m_pvtkImageActor->GetMapper()->SetInputConnection(GetDocument()->m_pvtkBMPReader->GetOutputPort());
        m_pvtkRenderer->AddActor(m_pvtkImageActor);
    }
}

You will find more details inside the sample project. Enjoy it!

 

30 Jan 2015 - I updated the code archive, I added Release folder to the archive.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Romania Romania
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionSDI can't display, though lots of try Pin
zeng_liwen19-Jan-19 8:45
zeng_liwen19-Jan-19 8:45 
AnswerRe: SDI can't display, though lots of try Pin
_Flaviu4-Aug-20 20:36
_Flaviu4-Aug-20 20:36 
QuestionVTK from mfc Pin
aroman19-Jul-18 4:00
aroman19-Jul-18 4:00 
AnswerRe: VTK from mfc Pin
Southmountain3-Jul-21 10:29
Southmountain3-Jul-21 10:29 
QuestionDo you have a permission problem? Pin
bosua28-Jun-18 18:13
bosua28-Jun-18 18:13 
QuestionDo you have the SDI version Pin
zeng_liwen21-Oct-17 2:26
zeng_liwen21-Oct-17 2:26 
AnswerRe: Do you have the SDI version Pin
_Flaviu23-Oct-17 4:37
_Flaviu23-Oct-17 4:37 
GeneralRe: Do you have the SDI version Pin
zeng_liwen20-Mar-18 16:42
zeng_liwen20-Mar-18 16:42 
I tried and tried, but it did not show the map.
// vtkSDIView.cpp : implementation of the CvtkSDIView class
//

#include "stdafx.h"
// SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
// and search filter handlers and allows sharing of document code with that project.
#ifndef SHARED_HANDLERS
#include "vtkSDI.h"
#endif

#include "vtkSDIDoc.h"
#include "vtkSDIView.h"

#include <vtkWin32OpenGLRenderWindow.h>
#include <vtkImageMapper3D.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CvtkSDIView

IMPLEMENT_DYNCREATE(CvtkSDIView, CView)

BEGIN_MESSAGE_MAP(CvtkSDIView, CView)
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CvtkSDIView::OnFilePrintPreview)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
	ON_WM_DESTROY()
	ON_WM_SIZE()
END_MESSAGE_MAP()

// CvtkSDIView construction/destruction

CvtkSDIView::CvtkSDIView()
{
	// TODO: add construction code here
    m_pvtkMFCWindow = NULL;
    m_pvtkRenderer = vtkRenderer::New();
    m_pvtkImageActor = vtkImageActor::New();

}

CvtkSDIView::~CvtkSDIView()
{
	if(NULL != m_pvtkMFCWindow)
        delete m_pvtkMFCWindow;
}

BOOL CvtkSDIView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

// CvtkSDIView drawing

void CvtkSDIView::OnDraw(CDC* pDC)
{
	CvtkSDIDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: add draw code for native data here
	if(NULL != m_pvtkMFCWindow && pDC->IsPrinting())
			m_pvtkMFCWindow->DrawDC(pDC);
}


// CvtkSDIView printing


void CvtkSDIView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
	AFXPrintPreview(this);
#endif
}

BOOL CvtkSDIView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CvtkSDIView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CvtkSDIView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

void CvtkSDIView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
	ClientToScreen(&point);
	OnContextMenu(this, point);
}

void CvtkSDIView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
	theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// CvtkSDIView diagnostics

#ifdef _DEBUG
void CvtkSDIView::AssertValid() const
{
	CView::AssertValid();
}

void CvtkSDIView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CvtkSDIDoc* CvtkSDIView::GetDocument() const // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CvtkSDIDoc)));
	return (CvtkSDIDoc*)m_pDocument;
}
#endif //_DEBUG


// CvtkSDIView message handlers


void CvtkSDIView::OnInitialUpdate()
{
	CView::OnInitialUpdate();

	// TODO: Add your specialized code here and/or call the base class
    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)
    {
        //setup renderer
        m_pvtkImageActor->GetMapper()->SetInputConnection(GetDocument()->m_pvtkBMPReader->GetOutputPort());
        m_pvtkRenderer->AddActor(m_pvtkImageActor);
    }
}


void CvtkSDIView::OnDestroy()
{
	    
	if(NULL != m_pvtkRenderer)
        m_pvtkRenderer->Delete();
    if(NULL != m_pvtkImageActor)
        m_pvtkImageActor->Delete();

	CView::OnDestroy();

	// TODO: Add your message handler code here

}


void CvtkSDIView::OnSize(UINT nType, int cx, int cy)
{
	CView::OnSize(nType, cx, cy);

	// TODO: Add your message handler code here
	if(NULL != m_pvtkMFCWindow)
        m_pvtkMFCWindow->MoveWindow(0, 0, cx, cy);
}

// vtkSDIView.h : interface of the CvtkSDIView class
//

#pragma once
#include "vtkMFCWindow.h"
#include "vtkRenderer.h"
#include "vtkImageActor.h"


class CvtkSDIView : public CView
{
protected: // create from serialization only
	CvtkSDIView();
	DECLARE_DYNCREATE(CvtkSDIView)

// Attributes
public:
	CvtkSDIDoc* GetDocument() const;

// Operations
public:

protected:
	vtkMFCWindow* m_pvtkMFCWindow;
	vtkRenderer* m_pvtkRenderer;
	vtkImageActor* m_pvtkImageActor;

// Overrides
public:
	virtual void OnDraw(CDC* pDC);  // overridden to draw this view
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// Implementation
public:
	virtual ~CvtkSDIView();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
	afx_msg void OnFilePrintPreview();
	afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
	DECLARE_MESSAGE_MAP()
public:
	virtual void OnInitialUpdate();
	afx_msg void OnDestroy();
	afx_msg void OnSize(UINT nType, int cx, int cy);
};

#ifndef _DEBUG  // debug version in vtkSDIView.cpp
inline CvtkSDIDoc* CvtkSDIView::GetDocument() const
   { return reinterpret_cast<CvtkSDIDoc*>(m_pDocument); }
#endif

Questionunresolved external symbol vtkMFCWindow::AssertValid and dump Pin
zeng_liwen7-Aug-17 23:37
zeng_liwen7-Aug-17 23:37 
AnswerRe: unresolved external symbol vtkMFCWindow::AssertValid and dump Pin
_Flaviu9-Aug-17 21:09
_Flaviu9-Aug-17 21:09 
QuestionCannot build INSTALL of VTK when adding MFC Pin
Member 131050954-Apr-17 2:25
Member 131050954-Apr-17 2:25 
AnswerRe: Cannot build INSTALL of VTK when adding MFC Pin
_Flaviu4-Apr-17 20:33
_Flaviu4-Apr-17 20:33 
GeneralRe: Cannot build INSTALL of VTK when adding MFC Pin
Member 131050955-Apr-17 1:02
Member 131050955-Apr-17 1:02 
AnswerRe: Cannot build INSTALL of VTK when adding MFC Pin
_Flaviu10-Apr-17 20:32
_Flaviu10-Apr-17 20:32 
AnswerRe: Cannot build INSTALL of VTK when adding MFC Pin
_Flaviu10-Apr-17 20:36
_Flaviu10-Apr-17 20:36 
GeneralRe: Cannot build INSTALL of VTK when adding MFC Pin
Member 1310509523-Apr-17 23:15
Member 1310509523-Apr-17 23:15 
Questionget several errors Pin
Member 1071490628-Dec-16 2:27
Member 1071490628-Dec-16 2:27 
AnswerRe: get several errors Pin
_Flaviu28-Dec-16 8:02
_Flaviu28-Dec-16 8:02 
GeneralRe: get several errors Pin
Member 1071490628-Dec-16 16:25
Member 1071490628-Dec-16 16:25 
Questionabout header file Pin
xuyunhai29-Oct-14 23:54
xuyunhai29-Oct-14 23:54 
AnswerRe: about header file Pin
_Flaviu30-Oct-14 0:23
_Flaviu30-Oct-14 0:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.