VTKをMFCのウィンドウに張り付ける。VTKのビルド時にMFCサポートを入れておく必要がある。
VTKのビルド時、VTK_MODULE_ENABLE_VTK_GUISupportMFCを設定しておく必要がある。
VTK_MODULE_ENABLE_VTK_GUISupportMFCをYESに設定。
この設定をすると、vtkMFCWindow.hなどが使用できるようになる。
MFCを使用するプロジェクトの設定を「マルチバイト文字セットを使用する」に変更する。
経験上、プロジェクト設定がUnicodeだとデバッグモードでウィンドウを作成できない(例外発生)。
この設定をしないと特にデバッグモードでvtkMFCWindow内でCWnd::Createのあたりで落ちる。
vtkMFCWindow::vtkMFCWindow(CWnd* pcWnd) { this->pvtkWin32OpenGLRW = nullptr; // create self as a child of passed in parent DWORD style = WS_VISIBLE | WS_CLIPSIBLINGS; if (pcWnd) style |= WS_CHILD; BOOL bCreated = CWnd::Create(nullptr, _T("VTK-MFC Window"), style, CRect(0, 0, 1, 1), pcWnd, (UINT)IDC_STATIC); SUCCEEDED(bCreated); // create a default vtk window vtkWin32OpenGLRenderWindow* win = vtkWin32OpenGLRenderWindow::New(); this->SetRenderWindow(win); win->Delete(); }
#pragma once /////////////////////////////// // VTKに必要 #include <vtkMFCWindow.h> // vtkMFCWindowを使うために必要 #include <vtkWin32OpenGLRenderWindow.h> // vtkMFCWindowを使うために必要 #include <vtkSmartPointer.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkConeSource.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkCamera.h> /* * 以下をはじめとする、wgl系のリンクエラーが出たら、opengl32.libをリンクする 1>vtkRenderingOpenGL2-9.3.lib(vtkWin32OpenGLRenderWindow.obj) : error LNK2001: 外部シンボル __imp_wglCreateContext は未解決です */ #pragma comment(lib,"opengl32.lib") /* 以下のエラーが出たら、Psapi.libをリンクする vtksys-9.3.lib(SystemInformation.obj) : error LNK2001: 外部シンボル GetProcessMemoryInfo は未解決です */ #pragma comment(lib, "Psapi.lib") /* 以下のエラーが出たら、Dbghelp.libをリンクする vtksys-9.3.lib(SystemInformation.obj) : error LNK2001: 外部シンボル __imp_SymGetLineFromAddr64 は未解決です vtksys-9.3.lib(SystemInformation.obj) : error LNK2001: 外部シンボル __imp_SymInitialize は未解決です vtksys-9.3.lib(SystemInformation.obj) : error LNK2001: 外部シンボル __imp_SymFromAddr は未解決です */ #pragma comment(lib, "Dbghelp.lib") class CChildView : public CWnd { vtkMFCWindow* m_vtkMFCWindow; /* 略 */ protected: afx_msg void OnPaint(); DECLARE_MESSAGE_MAP() public: afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnDestroy(); };
#include "pch.h" #include "framework.h" #include "MFCApplication4-with-vtk.h" #include "ChildView.h" // trackball 対応 #include <vtkInteractorStyleImage.h> #include <vtkWin32RenderWindowInteractor.h> //win32api対応 // vtkWin32RenderWindowInteractor.h 内でincludeされている //#include <vtkRenderWindowInteractor.h> #include <cstdio> #ifdef _DEBUG #define new DEBUG_NEW #endif // CChildView CChildView::CChildView() { m_vtkMFCWindow = nullptr; } CChildView::~CChildView() { } BEGIN_MESSAGE_MAP(CChildView, CWnd) ON_WM_PAINT() ON_WM_CREATE() ON_WM_SIZE() ON_WM_DESTROY() END_MESSAGE_MAP() // CChildView メッセージ ハンドラー BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) { if (!CWnd::PreCreateWindow(cs)) return FALSE; cs.dwExStyle |= WS_EX_CLIENTEDGE; cs.style &= ~WS_BORDER; cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, ::LoadCursor(nullptr, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), nullptr); return TRUE; } void CChildView::OnPaint() { CPaintDC dc(this); // 描画のデバイス コンテキスト
// 初回起動時のウィンドウサイズ指定 static bool firsttime = true; if (m_vtkMFCWindow && firsttime) { firsttime = false; // ウィンドウの現在のサイズを取得 CRect rect; GetClientRect(&rect); // VTKのウィンドウサイズを変更 m_vtkMFCWindow->GetRenderWindow()->SetSize(rect.right, rect.bottom); }
if (m_vtkMFCWindow) { m_vtkMFCWindow->DrawDC(&dc);// 描画 // こちらでもいい。 //m_vtkMFCWindow->GetRenderWindow()->Render(); }
} int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;
// VTKのMFC用ウィンドウ作成 m_vtkMFCWindow = new vtkMFCWindow(this); m_vtkMFCWindow->SetParent(this);
// レンダラーの作成 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); m_vtkMFCWindow->GetRenderWindow()->AddRenderer(renderer); // オブジェクトを作成・登録 vtkSmartPointer<vtkConeSource> coneSource; coneSource = vtkSmartPointer<vtkConeSource>::New(); vtkSmartPointer<vtkPolyDataMapper> mapper; mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputConnection(coneSource->GetOutputPort()); vtkSmartPointer<vtkActor> actor; actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); renderer->AddActor(actor); vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); m_vtkMFCWindow->GetRenderWindow()->SetInteractor(interactor); auto iren = vtkSmartPointer<vtkWin32RenderWindowInteractor>::New(); vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New(); iren->SetInteractorStyle(style); iren->SetRenderWindow(m_vtkMFCWindow->GetRenderWindow());
return 0; } void CChildView::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy);
// ウィンドウサイズの変更に合わせて // VTKの表示範囲を変更 RECT rect; m_vtkMFCWindow->MoveWindow(0, 0, cx,cy);
} void CChildView::OnDestroy() { CWnd::OnDestroy(); // これをしないとアプリケーション終了しようとしても // なぜか終了しないことがある PostQuitMessage(0); }