1 vtk
1.1 简要介绍
VTK(visualization toolkit)
是一个开源的BSD
许可证免费软件系统,主要用于三维计算机图形学、图像处理和科学计算可视化。VTK
是在三角函数库OpenGL
的基础上采用面向对象的设计方法发展起来的,它将我们在可视化开发过程中会经常遇到的细节屏蔽起来,并将一些常用的算法封装起来。
1.2 依赖库
vtk
一般不需要再配置其他库。
1.2.1 MPI
非必选,如果想要编译vtkIOMPIImage
或vtkIOMPIParallel
模块,需要依赖MPI
库,用于加速。MPI
库下载地址:
https://www.microsoft.com/en-us/download/details.aspx?id=57467
注:对于编译
vtk
,下载msmpisdk.msi
即可,即MPI
库的SDK
,安装后生成include
和Lib
两个文件夹。
1.3 源码包下载
vtk
源码地址:github
:https://github.com/Kitware/VTK.git
2 Cmake构建项目
2.1 路径
源代码路径:D:/ThirdParty/vtk/VTK_8.2.0
构建项目路径:D:/ThirdParty/vtk/VTK_8.2.0_build
2.2 构建选项
名称 | 值 | 备注 |
---|---|---|
BUILD_TESTING | false | |
CMAKE_INSTALL_PREFIX | path | 编译时生成的安装文件路径 |
CMAKE_DEBUG_POSTFIX | -d | debug 版本库名称后缀,需要勾选Cmake 中的Advanced |
CMAKE_CXX_MP_FLAG | true |
如果想要编译vtkIOMPIImage
或vtkIOMPIParallel
这两个模块,还需要如下设置:
名称 | 值 | 备注 |
---|---|---|
Module_vtkIOMPIImage | true | 编译vtkIOMPIImage 模块 |
Module_vtkIOMPIParallel | true | 编译vtkIOMPIParallel 模块 |
VTK_Group_MPI | true | |
MPI_CXX_INCLUDE_PATH | path | MPI 库Include 文件夹路径../mpi/Include |
MPI_CXX_LIBRARIES | path | MPI 库Lib 文件夹路径../mpi/Lib/x64 |
MPI_C_INCLUDE_PATH | path | MPI 库Include 文件夹路径../mpi/Include |
MPI_C_LIBRARIES | path | MPI 库Lib 文件夹路径../mpi/Lib/x64 |
注:这样的配置仅能保证
Configure
能过,Generate
代码时会有一堆报警,但也能成功生成项目,但这在编译vtkParallelMPI
,vtkIOMPIImage
和vtkIOParallelNetCDF
这3个项目时,仍会报MPI
中无法解析的外部符号错误,我是针对这3个项目,在附加依赖项中,手动添加了MPI
库Lib/x64
文件夹下的几个库文件名,我对cmake
不熟,没有找到更好的办法,大家要是有更好的方法,欢迎留言赐教。
另外,针对这3个项目,在附加库目录中,手动添加了MPI
库Include/x64
文件夹的路径。
2.3 构建项目
步骤如下:
- 指定源码路径;
- 指定构建项目路径;
- 点击
Configure
; - 按照2.2节表中的值进行设置;
- 再次点击
Configure
; - 点击
Generate
,构建项目路径中将生成解决方案文件VTK.sln
。
点击
Configure
或Generate
后,如果顺利,会出现Configuring done
或Generating done
。
3 打开解决方案并编译
3.1 编译解决方案
点击Open Project
(或者在2.3节步骤2中指定的构建项目路径中,找到生成的解决方案文件VTK.sln
,通过Visual Studio
打开),打开通过Cmake
构建的项目;
选中ALL_BUILD
项目,分别在Debug
和Release
模式下,重新生成解决方案。
3.2 安装vtk
选中INSTALL
项目,右击,重新生成,此时,将会在指定路径下(2.2节表中CMAKE_INSTALL_PREFIX
选项的值)主要生成3个文件夹include
和lib
和bin
。
4 实际项目环境配置
注:以下通过属性表的方式进行环境配置。
4.1 附加包含目录
$(vtk)\vtk-8.2\include
$(vtk)
(在系统环境变量中添加并设置)就是2.2节表中CMAKE_INSTALL_PREFIX
选项的值。
4.2 附加库目录
$(vtk)\lib
4.3 附加依赖项
将库目录$(vtk)\lib
中文件后缀名为.lib
的文件依次添加至附加依赖项中,并依次配置debug版本(文件名中有d
)和release版本。
注意,添加附加依赖项时,不要漏掉文件后缀名
.lib
!
4.4 动态库
将动态库目录添加至系统环境变量Path
,步骤如下:
- 计算机右击,点击“属性”;
- 点击“高级系统设置”;
- 点击“环境变量”;
- 双击
Path
; - 添加
%vtk%\bin
,该目录下是包含了动态库文件。
本文使用的都是相对路径,因此需事先设置好环境变量
vtk
,值为CMAKE_INSTALL_PREFIX
对应的目录,也可以使用绝对路径。
注:上述步骤是按照加载
vtk
动态库的方式进行配置的;
当然也可以按照静态库的方式配置,可省略步骤4.4
。
4.5 测试代码
/*=========================================================================
Program: Visualization Toolkit
Module: Cone.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
//
// This example creates a polygonal model of a cone, and then renders it to
// the screen. It will rotate the cone 360 degrees and then exit. The basic
// setup of source -> mapper -> actor -> renderer -> renderwindow is
// typical of most VTK programs.
//
// First include the required header files for the VTK classes we are using.
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
//#define vtkRenderingCore_AUTOINIT 2(vtkInteractionStyle,vtkRenderingOpenGL2)
#include "vtkConeSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkCamera.h"
#include "vtkActor.h"
#include "vtkRenderer.h"
int main()
{
//
// Next we create an instance of vtkConeSource and set some of its
// properties. The instance of vtkConeSource "cone" is part of a
// visualization pipeline (it is a source process object); it produces data
// (output type is vtkPolyData) which other filters may process.
//
vtkConeSource* cone = vtkConeSource::New();
cone->SetHeight(3.0);
cone->SetRadius(1.0);
cone->SetResolution(10);
//
// In this example we terminate the pipeline with a mapper process object.
// (Intermediate filters such as vtkShrinkPolyData could be inserted in
// between the source and the mapper.) We create an instance of
// vtkPolyDataMapper to map the polygonal data into graphics primitives. We
// connect the output of the cone source to the input of this mapper.
//
vtkPolyDataMapper* coneMapper = vtkPolyDataMapper::New();
coneMapper->SetInputConnection(cone->GetOutputPort());
//
// Create an actor to represent the cone. The actor orchestrates rendering
// of the mapper's graphics primitives. An actor also refers to properties
// via a vtkProperty instance, and includes an internal transformation
// matrix. We set this actor's mapper to be coneMapper which we created
// above.
//
vtkActor* coneActor = vtkActor::New();
coneActor->SetMapper(coneMapper);
//
// Create the Renderer and assign actors to it. A renderer is like a
// viewport. It is part or all of a window on the screen and it is
// responsible for drawing the actors it has. We also set the background
// color here.
//
vtkRenderer* ren1 = vtkRenderer::New();
ren1->AddActor(coneActor);
ren1->SetBackground(0.1, 0.2, 0.4);
//
// Finally we create the render window which will show up on the screen.
// We put our renderer into the render window using AddRenderer. We also
// set the size to be 300 pixels by 300.
//
vtkRenderWindow* renWin = vtkRenderWindow::New();
renWin->AddRenderer(ren1);
renWin->SetSize(300, 300);
//
// Now we loop over 360 degrees and render the cone each time.
//
int i;
for (i = 0; i < 360; ++i)
{
// render the image
renWin->Render();
// rotate the active camera by one degree
ren1->GetActiveCamera()->Azimuth(1);
}
//
// Free up any objects we created. All instances in VTK are deleted by
// using the Delete() method.
//
cone->Delete();
coneMapper->Delete();
coneActor->Delete();
ren1->Delete();
renWin->Delete();
std::system("pause");
return 0;
}
如果编译时报错,提示error LNK2019:无法解析的外部符号 __imp_SymGetLineFromAddr64
,解决方案如下:
“项目”–>“属性”–>“链接器”–>“输入”–>“附加依赖项”,添加dgbhelp.lib
。
如果运行时报错,提示Error: no override found for 'vtkPolyDataMapper'
,解决方案如下:
- 在附加依赖项中添加
opengl32.lib
; - 程序开头添加如下代码:
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2); // 也有可能是VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
或者程序开头直接添加一句代码:#define vtkRenderingCore_AUTOINIT 2(vtkInteractionStyle,vtkRenderingOpenGL2)
。
这句代码来源于编译代码生成目录
D:\ThirdParty\vtk\VTK_8.2.0_build\CMakeFiles
下的vtkRenderingCore_AUTOINIT_vtkInteractionStyle_vtkRenderingOpenGL2.h
文件内。