您的位置:首页 > 编程语言

VTK与MFC联合编程实现的单文档实例vtkSDI详解

2014-03-21 14:40 676 查看
1. 实例的编译运行

新建工程时,可以直接通过cmake生成,但如果工程没有编译完全或者安装成功的话,在安装目录没法找到GUISupport/MFC/VTKMFCSettings.cmake,从而无法正常新建工程。这里主要讲解手动新建工程的过程,以方便大家的学习

和进一步理解。

a.新建工程,然后将vtkSDI文件夹直接覆盖工程里面的文件,res文件可以不复制。

b.设置头文件



b.添加lib路径和文件



c.修改property里面的general选项里的character
set的设置。



d.编译运行



e.选择vtkdata中的vtk文件,然后进行查看处理





值得注意的是,要运用vtk和MFC联合编程,编译VTK源代码的时候一定要选择vtk gui support里的MFC.

2.实例源码详解

学过MFC的基本都知道,MFC中view类主要处理显示视图,doc类处理文档,mainframe主要为整个窗口的和工程的设置管理。由此,VTK与MFC联合编程时,需要主要的是数据操作,以及显示要很好的与MFC中的结构结合,做到MVC分离的要求和规范,视图-模型和控制一定要处理开来,尤其是大工程的处理时,才能不混乱。

a.view类设置

头文件

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

#pragma once
//添加MFC显示窗口的头文件
#include "vtkMFCWindow.h"

class CvtkSDIView : public CView
{
public:
virtual ~CvtkSDIView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif

CvtkSDIDoc* GetDocument() const;
//获得vtkRender的指针
vtkRenderer* GetRenderer() { ASSERT(pvtkRenderer); return pvtkRenderer; }

virtual void OnDraw(CDC* pDC);  // overridden to draw this view

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnSize(UINT nType, int cx, int cy);

private:
//显示的变量,vtkrender和vtkMFCWindow
vtkRenderer            *pvtkRenderer;
vtkMFCWindow          *pvtkMFCWindow;

protected:
DECLARE_DYNCREATE(CvtkSDIView)
CvtkSDIView();

virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

DECLARE_MESSAGE_MAP()
public:
virtual void OnInitialUpdate();
};

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


实现文件
// vtkSDIView.cpp : implementation of the CvtkSDIView class
//

#include "stdafx.h"
#include "vtkSDI.h"

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

#include "vtkCallbackCommand.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, CView::OnFilePrintPreview)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
END_MESSAGE_MAP()

// CvtkSDIView construction/destruction

CvtkSDIView::CvtkSDIView()
{
this->pvtkMFCWindow     = NULL;

//新建视图类对象
this->pvtkRenderer    = vtkRenderer::New();
}

CvtkSDIView::~CvtkSDIView()
{
// delete generic vtk window
if (this->pvtkMFCWindow) delete this->pvtkMFCWindow;
}

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

if (this->pvtkMFCWindow)
{
if (pDC->IsPrinting())
this->pvtkMFCWindow->DrawDC(pDC);
}
}

// CvtkSDIView printing

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
}

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

int CvtkSDIView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

return 0;
}

void CvtkSDIView::OnDestroy()
{
// Delete the the renderer, window and interactor objects.
if (this->pvtkRenderer)      this->pvtkRenderer->Delete();

// destroy base
CView::OnDestroy();
}

BOOL CvtkSDIView::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}

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

if (this->pvtkMFCWindow)
this->pvtkMFCWindow->MoveWindow(0, 0, cx, cy);
}

static void handle_double_click(vtkObject* obj, unsigned long,
void*, void*)
{
//交互响应回调函数,输出提示信息
vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::SafeDownCast(obj);
if(iren && iren->GetRepeatCount())
{
AfxMessageBox("Double Click");
}
}

void CvtkSDIView::OnInitialUpdate()
{
CView::OnInitialUpdate();
//初始化的时候创建vtkMFCwindow对象
if (this->pvtkMFCWindow) delete this->pvtkMFCWindow;
this->pvtkMFCWindow = new vtkMFCWindow(this);
//将render对象添加到实现窗口vtkMFCwindow中
this->pvtkMFCWindow->GetRenderWindow()->AddRenderer(this->pvtkRenderer);

//添加交互中鼠标左键响应回调函数
vtkCallbackCommand* callback = vtkCallbackCommand::New();
callback->SetCallback(handle_double_click);
this->pvtkMFCWindow->GetInteractor()->AddObserver(vtkCommand::LeftButtonPressEvent, callback, 1.0);
callback->Delete();

}


a.Doc类设置

头文件

// vtkSDIDoc.h : interface of the CvtkSDIDoc class
//

#pragma once

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

// Attributes
private:
vtkDataSetReader *pvtkDataSetReader;

// Operations
public:

// Overrides
public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);

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

private:
void ExecutePipeline();
void RemoveActors();
//数据处理和显示的mapper和actor对象
vtkDataSetMapper  *pvtkDataSetMapper;
vtkActor      *pvtkActor;

vtkActor2D      *pvtkActor2D;
vtkTextMapper    *pvtkTextMapper;

// Generated message map functions
protected:
DECLARE_MESSAGE_MAP()
public:
virtual void OnCloseDocument();
virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
};


实现文件
// vtkSDIDoc.cpp : implementation of the CvtkSDIDoc class
//

#include "stdafx.h"
#include "vtkSDI.h"

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

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CvtkSDIDoc

IMPLEMENT_DYNCREATE(CvtkSDIDoc, CDocument)

BEGIN_MESSAGE_MAP(CvtkSDIDoc, CDocument)
END_MESSAGE_MAP()

// CvtkSDIDoc construction/destruction

CvtkSDIDoc::CvtkSDIDoc()
{
this->pvtkDataSetReader  = NULL;

// 创建对象,从而可以显示
this->pvtkDataSetMapper  = vtkDataSetMapper::New();
this->pvtkActor      = vtkActor::New();
this->pvtkActor2D    = vtkActor2D::New();
this->pvtkTextMapper  = vtkTextMapper::New();
}

CvtkSDIDoc::~CvtkSDIDoc()
{
}

BOOL CvtkSDIDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;

//移除原有actor对象
RemoveActors();

//执行数据处理流程
ExecutePipeline();

return TRUE;
}

// CvtkSDIDoc serialization

void CvtkSDIDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}

// CvtkSDIDoc diagnostics

#ifdef _DEBUG
void CvtkSDIDoc::AssertValid() const
{
CDocument::AssertValid();
}

void CvtkSDIDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG

// CvtkSDIDoc commands

void CvtkSDIDoc::RemoveActors()
{
//活的view类对象
POSITION pos = this->GetFirstViewPosition();
CvtkSDIView *pcvtkSDIView = NULL;

if (pos)
{
pcvtkSDIView = (CvtkSDIView *)GetNextView(pos);
}
else  // return
{
ASSERT(FALSE);
return;
}

//移除actor对象
pcvtkSDIView->GetRenderer()->RemoveActor(this->pvtkActor);
pcvtkSDIView->GetRenderer()->RemoveActor(this->pvtkActor2D);
}
//openfile 打开数据文件,将数据导入
BOOL CvtkSDIDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;

//移除对象
RemoveActors();

//读入数据
this->pvtkDataSetReader = vtkDataSetReader::New();
this->pvtkDataSetReader->SetFileName(lpszPathName);

//运行数据导入流程,导入数据
ExecutePipeline();

return TRUE;
}
//释放创建的内存
void CvtkSDIDoc::OnCloseDocument()
{
// delete data
if (this->pvtkDataSetReader)  this->pvtkDataSetReader->Delete();

// Delete the the objects used to form the visualisation.
if (this->pvtkDataSetMapper)  this->pvtkDataSetMapper->Delete();
if (this->pvtkActor)      this->pvtkActor->Delete();
if (this->pvtkActor2D)      this->pvtkActor2D->Delete();
if (this->pvtkTextMapper)    this->pvtkTextMapper->Delete();

CDocument::OnCloseDocument();
}
//数据处理流程
void CvtkSDIDoc::ExecutePipeline()
{
// 获得视图类对象
POSITION pos = this->GetFirstViewPosition();
CvtkSDIView *pcvtkSDIView = NULL;

if (pos)
{
pcvtkSDIView = (CvtkSDIView *)GetNextView(pos);
}
else  // return
{
ASSERT(FALSE);
return;
}

if (pvtkDataSetReader)  // 有数据,将数据添加到render中显示
{
this->pvtkDataSetMapper->SetInput(this->pvtkDataSetReader->GetOutput());
this->pvtkActor->SetMapper(this->pvtkDataSetMapper);

this->pvtkTextMapper->SetInput(this->pvtkDataSetReader->GetFileName());
this->pvtkTextMapper->GetTextProperty()->SetFontSize(12);
this->pvtkActor2D->SetMapper(this->pvtkTextMapper);

pcvtkSDIView->GetRenderer()->SetBackground(0.0,0.0,0.4);
pcvtkSDIView->GetRenderer()->AddActor(this->pvtkActor);
pcvtkSDIView->GetRenderer()->AddActor(this->pvtkActor2D);
pcvtkSDIView->GetRenderer()->ResetCamera();
pvtkDataSetReader->Delete();
pvtkDataSetReader = NULL;
}
else  //无导入数据,显示textmapper, hello world
{
this->pvtkTextMapper->SetInput("Hello World");
this->pvtkTextMapper->GetTextProperty()->SetFontSize(24);
this->pvtkActor2D->SetMapper(this->pvtkTextMapper);

pcvtkSDIView->GetRenderer()->SetBackground(0.0,0.0,0.4);
pcvtkSDIView->GetRenderer()->AddActor(this->pvtkActor2D);
pcvtkSDIView->GetRenderer()->ResetCamera();
}
}


好了,到这里,基本对MFC和vtk联合编程就有了个详细的了解了,这样也就可以自己用VTK结合MFC构建自己的工程了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: