1.下载VTK https://www.vtk.org/download下载好后,解压压缩包,我解压在/Users/chentingxuan/Downloads/VTK-8.1.2
新建一个code文件夹用于放编译后的代码,这样可以避免污染VTK源码,我放在了/Users/chentingxuan/Downloads/VTK-8.1.2-code 目录下
2.QT5.12.0直接去官网下载然后安装就好,傻瓜式安装就行。
3.下载cmake https://cmake.org/download ,然后安装,没啥难度
4.配置
1)在第一个框输入VTK路径,/Users/chentingxuan/Downloads/VTK-8.1.2
2)第二个框输入放代码的路径,/Users/chentingxuan/Downloads/VTK-8.1.2-code
3)点Configure,出来一个选择Generator的框,选择Unix Makefile,其它默认就好,然后确定(down)
4)根据你自己的模块,选择相应的模块就好,以下是我选择的
第一次会出现很多红的,没事,选择你所需要的模块后,再configure一次。第二次,如果还有红的,就要去查原因了。比如说,碰到Qt5_DIR_NOTFOUND,这个时候,你就需要手动改一下值:
当你没有出现红色的时候,就表示成功了
5)选择generate
5 安装
1)打开终端,切换到你刚刚generate到目录
2)输入命令,make -j8,其中-j8 为多线程执行命令,加速编译过程
以下就为编译过程:
如果在编译过程中,出现了错误,比如说某个头文件找不到:
那就进入相应的目录下,将该头文件给注释掉后,再重新编译
编译结束后,再输入make install -j8,进行安装
在安装的时候,如果出现了权限问题,如下:
则将输入sudo make install重新安装一次,并输入你的密码:
安装成功后,你可以在终端里切换到/usr/local/include ,然后输入ls,看一下该目录下面是否有vtk-8.1,如果有,就表示安装成功了。
6. 使用
创建QT工程
1)新建工程 > New Project
2)选择项目Application > Qt Widgets Application > next
3)工程名tesVTK,工程路径随便
4)之后一直默认选择,创建完成。
然后对新建工程配置VTK路径链接,即你刚刚安装成功后到路径链接。
工程中的testVTK.pro即为工程自动生成的配置文件,我们只需要在此文件上添加需要用的配置,当然如果不知道自己用到哪些链接库,可全部添加。
INCLUDEPATH+= /usr/local/include/vtk-8.1
LIBS +=-L/usr/local/lib -lvtkChartsCore-8.1.1 \
-lvtkCommonColor-8.1.1 \
-lvtkCommonComputationalGeometry-8.1.1 \
-lvtkCommonCore-8.1.1 \
-lvtkCommonDataModel-8.1.1 \
-lvtkCommonExecutionModel-8.1.1 \
-lvtkCommonMath-8.1.1 \
-lvtkCommonMisc-8.1.1 \
-lvtkCommonSystem-8.1.1 \
-lvtkCommonTransforms-8.1.1 \
-lvtkDICOMParser-8.1.1 \
-lvtkDomainsChemistry-8.1.1 \
-lvtkFiltersAMR-8.1.1 \
-lvtkFiltersCore-8.1.1 \
-lvtkFiltersExtraction-8.1.1 \
-lvtkFiltersFlowPaths-8.1.1 \
-lvtkFiltersGeneral-8.1.1 \
-lvtkFiltersGeneric-8.1.1 \
-lvtkFiltersGeometry-8.1.1 \
-lvtkFiltersHybrid-8.1.1 \
-lvtkFiltersHyperTree-8.1.1 \
-lvtkFiltersImaging-8.1.1 \
-lvtkFiltersModeling-8.1.1 \
-lvtkFiltersParallel-8.1.1 \
-lvtkFiltersParallelImaging-8.1.1 \
-lvtkFiltersPoints-8.1.1 \
-lvtkFiltersProgrammable-8.1.1 \
-lvtkFiltersSMP-8.1.1 \
-lvtkFiltersSelection-8.1.1 \
-lvtkFiltersSources-8.1.1 \
-lvtkFiltersStatistics-8.1.1 \
-lvtkFiltersTexture-8.1.1 \
-lvtkFiltersTopology-8.1.1 \
-lvtkFiltersVerdict-8.1.1 \
-lvtkGUISupportQt-8.1.1 \
-lvtkGUISupportQtSQL-8.1.1 \
-lvtkGeovisCore-8.1.1 \
-lvtkIOAMR-8.1.1 \
-lvtkIOCore-8.1.1 \
-lvtkIOEnSight-8.1.1 \
-lvtkIOExodus-8.1.1 \
-lvtkIOExport-8.1.1 \
-lvtkIOExportOpenGL2-8.1.1 \
-lvtkIOGeometry-8.1.1 \
-lvtkIOImage-8.1.1 \
-lvtkIOImport-8.1.1 \
-lvtkIOInfovis-8.1.1 \
-lvtkIOLSDyna-8.1.1 \
-lvtkIOLegacy-8.1.1 \
-lvtkIOMINC-8.1.1 \
-lvtkIOMovie-8.1.1 \
-lvtkIONetCDF-8.1.1 \
-lvtkIOPLY-8.1.1 \
-lvtkIOParallel-8.1.1 \
-lvtkIOParallelXML-8.1.1 \
-lvtkIOSQL-8.1.1 \
-lvtkIOVideo-8.1.1 \
-lvtkIOXML-8.1.1 \
-lvtkIOXMLParser-8.1.1 \
-lvtkImagingColor-8.1.1 \
-lvtkImagingCore-8.1.1 \
-lvtkImagingFourier-8.1.1 \
-lvtkImagingGeneral-8.1.1 \
-lvtkImagingHybrid-8.1.1 \
-lvtkImagingMath-8.1.1 \
-lvtkImagingMorphological-8.1.1 \
-lvtkImagingSources-8.1.1 \
-lvtkImagingStatistics-8.1.1 \
-lvtkImagingStencil-8.1.1 \
-lvtkInfovisCore-8.1.1 \
-lvtkInfovisLayout-8.1.1 \
-lvtkInteractionImage-8.1.1 \
-lvtkInteractionStyle-8.1.1 \
-lvtkInteractionWidgets-8.1.1 \
-lvtkLocalExample-8.1.1 \
-lvtkNetCDF-8.1.1 \
-lvtkParallelCore-8.1.1 \
-lvtkRenderingAnnotation-8.1.1 \
-lvtkRenderingContext2D-8.1.1 \
-lvtkRenderingCore-8.1.1 \
-lvtkRenderingFreeType-8.1.1 \
-lvtkRenderingImage-8.1.1 \
-lvtkRenderingLOD-8.1.1 \
-lvtkRenderingLabel-8.1.1 \
-lvtkRenderingQt-8.1.1 \
-lvtkRenderingVolume-8.1.1 \
-lvtkViewsContext2D-8.1.1 \
-lvtkRenderingContextOpenGL2-8.1.1 \
-lvtkViewsCore-8.1.1 \
-lvtkRenderingFreeType-8.1.1 \
-lvtkRenderingGL2PSOpenGL2-8.1.1 \
-lvtkRenderingImage-8.1.1 \
-lvtkRenderingLOD-8.1.1 \
-lvtkRenderingLabel-8.1.1 \
-lvtkRenderingOpenGL2-8.1.1 \
-lvtkRenderingQt-8.1.1 \
-lvtkRenderingVolume-8.1.1 \
-lvtkRenderingVolumeOpenGL2-8.1.1 \
-lvtkViewsContext2D-8.1.1 \
-lvtkViewsCore-8.1.1 \
-lvtkViewsInfovis-8.1.1 \
-lvtkViewsQt-8.1.1 \
-lvtkalglib-8.1.1 \
-lvtkexoIIc-8.1.1 \
-lvtkexpat-8.1.1 \
-lvtkfreetype-8.1.1 \
-lvtkgl2ps-8.1.1 \
-lvtkhdf5-8.1.1 \
-lvtkhdf5_hl-8.1.1 \
-lvtkjpeg-8.1.1 \
-lvtkjsoncpp-8.1.1 \
-lvtklibharu-8.1.1 \
-lvtklibxml2-8.1.1 \
-lvtklz4-8.1.1 \
-lvtkmetaio-8.1.1 \
-lvtknetcdfcpp-8.1.1 \
-lvtkoggtheora-8.1.1 \
-lvtkpng-8.1.1 \
-lvtkproj4-8.1.1 \
-lvtksqlite-8.1.1 \
-lvtksys-8.1.1 \
-lvtktiff-8.1.1 \
-lvtkverdict-8.1.1 \
-lvtkzlib-8.1.1
VTK安装路径一般在/usr/local/include 和 /usr/local/lib下。mac下的动态链接库后缀是.dylib,如libvtkRenderingQt-8.1.dylib,配置时需把lib 改成 -l,去掉.dylib。这里对于有个技巧可以列出所有的链接库,使用ls -1 /usr/local/lib/libvtk*命令单列列出链接库,复制文本再替换就行了。
测试一个例子
修改main.cpp如下:
#include "mainwindow.h"
#include <QApplication>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
#define vtkRenderingCore_AUTOINIT 4(vtkInteractionStyle,vtkRenderingFreeType,vtkRenderingFreeTypeOpenGL,vtkRenderingOpenGL)
#define vtkRenderingVolume_AUTOINIT 1(vtkRenderingVolumeOpenGL)
#include <vtkVersion.h>
#include <vtkPlaneSource.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
int main(int, char *[])
{
// Create a plane
vtkSmartPointer<vtkPlaneSource> planeSource = vtkSmartPointer<vtkPlaneSource>::New();
planeSource->SetCenter(1.0, 0.0, 0.0);
planeSource->SetNormal(1.0, 0.0, 1.0);
planeSource->Update();
vtkPolyData* plane = planeSource->GetOutput();
// Create a mapper and actor
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(plane);
#else
mapper->SetInputData(plane);
#endif
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// Create a renderer, render window and interactor
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
// Add the actors to the scene
renderer->AddActor(actor);
renderer->SetBackground(.1,.2,.3); // Background color dark blue
// Render and interact
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
这个时候,你点击运行,会发现出BUG了,这个我找了好久??,说什么(? error: symbol(s) not found for architecture x86_64)、(? error: linker command failed with exit code 1 (use -v to see invocation))
然后,在QT的编译输出里,又会出现下图所示:
Undefined symbols for architecture x86_64:
"vtkRenderingOpenGL_AutoInit_Destruct()", referenced from:
vtkRenderingOpenGL_ModuleInit::~vtkRenderingOpenGL_ModuleInit() in main.o
vtkRenderingCore_AutoInit::~vtkRenderingCore_AutoInit() in main.o
"vtkRenderingOpenGL_AutoInit_Construct()", referenced from:
vtkRenderingOpenGL_ModuleInit::vtkRenderingOpenGL_ModuleInit() in main.o
vtkRenderingCore_AutoInit::vtkRenderingCore_AutoInit() in main.o
"vtkRenderingFreeTypeOpenGL_AutoInit_Destruct()", referenced from:
vtkRenderingCore_AutoInit::~vtkRenderingCore_AutoInit() in main.o
"vtkRenderingFreeTypeOpenGL_AutoInit_Construct()", referenced from:
vtkRenderingCore_AutoInit::vtkRenderingCore_AutoInit() in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [tesVTK.app/Contents/MacOS/tesVTK] Error 1
然后,我又回头去看了自己编译的动态链接库,发现,我在CMake的时候,是make的OpenGL2,所以,我在main.cpp里面,所有与OpenGL有关的,都在后面加了一个2,例如把原来的VTK_MODULE_INIT(vtkRenderingOpenGL);改为了VTK_MODULE_INIT(vtkRenderingOpenGL2);
但是,这样还是有问题:
Undefined symbols for architecture x86_64:
"vtkRenderingFreeTypeOpenGL2_AutoInit_Destruct()", referenced from:
vtkRenderingCore_AutoInit::~vtkRenderingCore_AutoInit() in main.o
"vtkRenderingFreeTypeOpenGL2_AutoInit_Construct()", referenced from:
vtkRenderingCore_AutoInit::vtkRenderingCore_AutoInit() in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [tesVTK.app/Contents/MacOS/tesVTK] Error 1
19:56:05: 进程"/usr/bin/make"退出,退出代码 2 。
Error while building/deploying project tesVTK (kit: Desktop Qt 5.12.0 clang 64bit)
When executing step "Make"
到了这,我已经很想放弃了,但是又不能放弃,所以啊,我继续肝?
尝试按照网上的说法,去改QT安装目录下的qmake.config文件,将里面的系统的版本号改成当前最新的系统版本号,然而我的那个文件里面并没有那个系统的版本号,然后尼,我就糊里糊涂地去把两行代码给注释掉,发现就通了,对,居然跑起来了。
测试结果如下:
哈哈,真的太佩服自己了,肝了一天了,总算是把VTK的环境搭建好了,也怪自己太菜??,居然肝了一天。
这样虽然运行出来了,但是下面有一个警告:
(Warning: In /Users/chentingxuan/Downloads/VTK-8.1.2/Rendering/Core/vtkInteractorStyleSwitchBase.cxx, line 43
vtkInteractorStyleSwitchBase (0x7f9234c0b320): Warning: Link to vtkInteractionStyle for default style selection.
)
这个时候,只需要加两行代码就行
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
这个时候,再运行,就不会有任何的警告 了。最终的main.cpp的代码如下:
#include "mainwindow.h"
#include <QApplication>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
//#define vtkRenderingCore_AUTOINIT 4(vtkInteractionStyle,vtkRenderingFreeType,vtkRenderingFreeTypeOpenGL2,vtkRenderingOpenGL2)
//#define vtkRenderingVolume_AUTOINIT 1(vtkRenderingVolumeOpenGL2)
#include <vtkVersion.h>
#include <vtkPlaneSource.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
int main(int, char *[])
{
// Create a plane
vtkSmartPointer<vtkPlaneSource> planeSource = vtkSmartPointer<vtkPlaneSource>::New();
planeSource->SetCenter(1.0, 0.0, 0.0);
planeSource->SetNormal(1.0, 0.0, 1.0);
planeSource->Update();
vtkPolyData* plane = planeSource->GetOutput();
// Create a mapper and actor
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(plane);
#else
mapper->SetInputData(plane);
#endif
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// Create a renderer, render window and interactor
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
// Add the actors to the scene
renderer->AddActor(actor);
renderer->SetBackground(.1,.2,.3); // Background color dark blue
// Render and interact
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}