在9月中旬的时候,接下了这个铁路安全识别的项目,项目的主要内容是利用点云数据来进行处理。前文有提到前期一两个月主要是在做前期的文献工作,基本确定了数据采集的方案、对象识别的方案和安全计算的方案,这里就不再赘述了。自己之前在这个领域也没什么研究,完全是一遍踩坑一边做,网上几乎没有针对macOS平台配置开发的文章,所以这篇主要来聊一聊这个以PCL为主体的在macOS开发环境下的配置。

前言

个人其实不太爱用cpp这一套东西,所以最开始是准备用Python来实现这些内容,因为Python有比较方便的语言特性,加上各种科学计算库的支持,可以说是做这些研究非常好的工具了。通过Homebrew安装好pyenv后,构建一个3.4.9的版本(原因是一些诸如pyflann的库最高支持到这个版本),然后用virtualenv构建一个专属的虚拟环境。pip安装一些必要的三方库,再通过homebrew利用源码编译安装PCL,用以支援PyPCL。安装PCL的过程就是惯例的从源码编译安装,这个过程会比较漫长,如果设备里预先没有配置好环境就需要通过homebrew自动安装多个依赖,如下图所示:

安装pcl

最后配置完,使用的时候就犯难了,因为Py这一套东西处理数据量巨大的点云是在是有点慢,而且PyPCL的功能也并没有完全开发完毕,只能做一些比较初步的处理工作,所以我选择重新配置一套cpp的开发环境来做后续的开发。

pypcl

通过Homebrew配置工具和库文件

首先给出需要的软件列表:

  • Qt 5.11.2
  • PCL 1.8.1(依赖较多如下子列表所示,均可通过homebrew自动安装)
    • VTK 8.1.1
    • Eigen 3.3.5
    • boost 1.67.0
    • flann 1.9.1
    • qhull 2015.2
  • IDE工具:可选Clion/Qt-Creator,Clion意味着需要手工撰写CMakeList,配置与Qt的连接。Qt-Creator相对整合度更高,但是配置库和link比较复杂。针对这个问题后文做详细说明。
    • Clion从JetBrain官网下载安装,没有Community版本,购买或者使用学生免费License
    • Qt-Creator使用Homebrew-Cask安装即可
  • OS版本:macOS Mojave 10.14.1(这里是个比较坑的地方,Qt目前还未针对10.14的SDK做适配,虽然目前没遇到什么比较严重的问题,但是还是停留在10.13比较好)

编写第一个程序(Clion版)

首先我们来配置CMakeList

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cmake_minimum_required(VERSION 3.12)
project(point_cloud_tool)

# 设置CPP使用c++14
set(CMAKE_CXX_STANDARD 14)

# PCL库的配置
find_package(PCL REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

# Qt库的配置
set(CMAKE_PREFIX_PATH "/usr/local/opt/qt/lib") #这个路径写qt安装路径下的lib目录
# find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR on)
# 开启AUTOMOC
set(CMAKE_AUTOMOC ON)
# 开启AUTOUIC,这个是为了自动编译.ui文件
set(CMAKE_AUTOUIC ON)
# 开启UATORCC,这个是为了自动编译资源配置文件
set(CMAKE_AUTORCC ON)
# 找到我们需要的最核心的控件,就是QtWidgets
find_package(Qt5Widgets CONFIG REQUIRED)

# 设置编译的SOURCE_FILES
set(SOURCE_FILES main.cpp ui/main_window.cpp tool/triangulation.cpp)
add_executable(point_cloud_tool ${SOURCE_FILES} main_window.qrc)
target_link_libraries(point_cloud_tool ${PCL_LIBRARIES} Qt5::Widgets)

利用Qt-Designer设计程序界面

*开始设计界面之前,我们需要手工把qvtkWidget的dylib加入到Qt-Designer的插件文件夹中,方法如下:

1
cp /usr/local/Cellar/vtk/8.1.1_2/plugins/designer/libQVTKWidgetPlugin.dylib /usr/local/Cellar/qt/5.11.2/plugins/designer

通过Homebrew安装Qt后,Designer并不会自动加入到bin目录执行,所以我们利用命令行进入目录打开,并新建一个MainWindow:

1
open /usr/local/Cellar/qt/5.11.2/libexec/Designer.app

我们在上方的QMenuBar中添加一个打开的action:

designer1

再在左侧窗口部件盒中拉到最下方找到QVTKWidget,拖动放置于MainWindow中,并选择MainWindow设置栅格布局:

designer2

设计好后保存.ui文件,放入未来与MainWindow class同级的目录即可。

程序逻辑主体部分

我们切换回Clion,新建main.cpp,mainwindow.cpp和mainwindow.h

mainwindow.h

这里需要注意的一点是,可能会出现的一个运行时错误:no override found for ‘vtkRenderWindow’,这时我们需要在使用VTK控件的头部区域写上如下内容:

1
2
3
#include <vtkAutoInit.h> 
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#ifndef PCL_TRIANGULATION_PCL_VISUALIZER_H
#define PCL_TRIANGULATION_PCL_VISUALIZER_H

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);

#include <QtWidgets/QMainWindow>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include "ui/ui_main_window.h"


class MainWindowClass : public QMainWindow {
Q_OBJECT

public:
MainWindowClass(QWidget *parent = 0);

~MainWindowClass();

private:
Ui::MainWindowClass ui;

// 存储点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;

// 初始化vtk
void InitialVtkWidget();

private slots:

// 创建打开槽
void OpenFile();

void DisplayTrangles();
};


#endif //PCL_TRIANGULATION_PCL_VISUALIZER_H

mainwindow.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <QFileDialog>
#include <QMessageBox>
#include <iostream>
#include <vtkRenderWindow.h>
#include "tool/triangulation.h"

#include "main_window.h"

MainWindowClass::MainWindowClass(QWidget *parent)
: QMainWindow(parent) {
ui.setupUi(this);
// 初始化
InitialVtkWidget();
// 连接信号和槽
connect(ui.actionOpen, SIGNAL(triggered()), this, SLOT(OpenFile()));
}

MainWindowClass::~MainWindowClass() {

}

void MainWindowClass::InitialVtkWidget() {
cloud.reset(new pcl::PointCloud<pcl::PointXYZ>);
viewer.reset(new pcl::visualization::PCLVisualizer("point cloud viewer", false));
viewer->addPointCloud(cloud, "cloud");

ui.qvtkWidget->SetRenderWindow(viewer->getRenderWindow());
viewer->setupInteractor(ui.qvtkWidget->GetInteractor(), ui.qvtkWidget->GetRenderWindow());
ui.qvtkWidget->update();
}

// 读取文本和二进制点云数据
void MainWindowClass::OpenFile() {
// 打开pcd文件
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open PointCloud"), ".",
tr("Open PCD files(*.pcd)"));

if (!fileName.isEmpty()) {
std::string file_name = fileName.toStdString();
pcl::PCLPointCloud2 cloud2;
Eigen::Vector4f origin;
Eigen::Quaternionf orientation;
int pcd_version;
int data_type;
unsigned int data_idx;
int offset = 0;
pcl::PCDReader rd;
rd.readHeader(file_name, cloud2, origin, orientation, pcd_version, data_type, data_idx);

if (data_type == 0)
{
pcl::io::loadPCDFile(fileName.toStdString(), *cloud);
} else if (data_type == 2)
{
pcl::PCDReader reader;
reader.read<pcl::PointXYZ>(fileName.toStdString(), *cloud);
}

viewer->updatePointCloud(cloud, "cloud");
viewer->resetCamera();
ui.qvtkWidget->update();
}
}

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
#include <QtWidgets/QApplication>
#include "ui/main_window.h"

int main(int argc, char **argv)
{
// turn support for high DPI screens on
// QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
MainWindowClass w;
w.show();
return app.exec();
}

后续程序的主体部分参考了『吕小猪不坏』的一篇文章:

编写第一个程序(Qt-Creator版)

程序主体部分大致相同,这个就不在重复了,另外UI设计可以通过Qt-Creator内建的设计来完成,不过缺点是不能使用qvtkWidget的插件,因为百分百会导致IDE崩溃,这个也没有很好的解决办法。只能通过建立QWidget控件,然后使用“提升为”选择qvtkWidget.h来实现我们需要的功能。这个部分主要的区别只有一个就是库的引入和连接。

以下是一个超长的.pro文件列表,INCLUDE很简单,但是LIBS需要通过-L写明路径再-l写明需要引入的dylib,这一点非常不智能,每一个dylib都需要自己手动写好才可以正常连接。这里有一个小技巧方便获取所有的文件名称:

dylib

获取到之后直接选择复制,然后修改成需要的格式就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#-------------------------------------------------
#
# Project created by QtCreator 2018-11-13T15:57:55
#
#-------------------------------------------------

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = point_cloud_tool
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

CONFIG += c++14

SOURCES += \
main.cpp \
algorithm/triangulation.cpp \
mainwindow.cpp

HEADERS += \
mainwindow.h \
algorithm/triangulation.h

FORMS += \
gui/mainwindow.ui

RESOURCES += \
resources/mainwindow.qrc

# include & libs
# PCL
INCLUDEPATH += /usr/local/Cellar/pcl/1.8.1_5/include/pcl-1.8
INCLUDEPATH += /usr/local/Cellar/vtk/8.1.1_2/include/vtk-8.1
INCLUDEPATH += /usr/local/Cellar/eigen/3.3.5/include/eigen3
INCLUDEPATH += /usr/local/Cellar/boost/1.67.0_1/include
INCLUDEPATH += /usr/local/Cellar/flann/1.9.1_6/include
INCLUDEPATH += /usr/local/Cellar/qhull/2015.2/include

LIBS += -L/usr/local/Cellar/pcl/1.8.1_5/lib -lpcl_apps.1.8.1 \
-lpcl_common.1.8.1 \
-lpcl_features.1.8.1 \
-lpcl_filters.1.8.1 \
-lpcl_io.1.8.1 \
-lpcl_io_ply.1.8.1 \
-lpcl_kdtree.1.8.1 \
-lpcl_keypoints.1.8.1 \
-lpcl_ml.1.8.1 \
-lpcl_octree.1.8.1 \
-lpcl_outofcore.1.8.1 \
-lpcl_people.1.8.1 \
-lpcl_recognition.1.8.1 \
-lpcl_registration.1.8.1 \
-lpcl_sample_consensus.1.8.1 \
-lpcl_search.1.8.1 \
-lpcl_segmentation.1.8.1 \
#-lpcl_simulation.1.8.1 \
#-lpcl_simulation_io.1.8.1 \
-lpcl_stereo.1.8.1 \
-lpcl_surface.1.8.1 \
-lpcl_tracking.1.8.1 \
-lpcl_visualization.1.8.1

LIBS += -L/usr/local/Cellar/vtk/8.1.1_2/lib -lvtkChartsCore-8.1.1 \
-lvtkChartsCorePython27D-8.1.1 \
-lvtkCommonColor-8.1.1 \
-lvtkCommonColorPython27D-8.1.1 \
-lvtkCommonComputationalGeometry-8.1.1 \
-lvtkCommonComputationalGeometryPython27D-8.1.1 \
-lvtkCommonCore-8.1.1 \
-lvtkCommonCorePython27D-8.1.1 \
-lvtkCommonDataModel-8.1.1 \
-lvtkCommonDataModelPython27D-8.1.1 \
-lvtkCommonExecutionModel-8.1.1 \
-lvtkCommonExecutionModelPython27D-8.1.1 \
-lvtkCommonMath-8.1.1 \
-lvtkCommonMathPython27D-8.1.1 \
-lvtkCommonMisc-8.1.1 \
-lvtkCommonMiscPython27D-8.1.1 \
-lvtkCommonSystem-8.1.1 \
-lvtkCommonSystemPython27D-8.1.1 \
-lvtkCommonTransforms-8.1.1 \
-lvtkCommonTransformsPython27D-8.1.1 \
-lvtkDICOMParser-8.1.1 \
-lvtkDomainsChemistry-8.1.1 \
-lvtkDomainsChemistryOpenGL2-8.1.1 \
-lvtkDomainsChemistryOpenGL2Python27D-8.1.1 \
-lvtkDomainsChemistryPython27D-8.1.1 \
-lvtkFiltersAMR-8.1.1 \
-lvtkFiltersAMRPython27D-8.1.1 \
-lvtkFiltersCore-8.1.1 \
-lvtkFiltersCorePython27D-8.1.1 \
-lvtkFiltersExtraction-8.1.1 \
-lvtkFiltersExtractionPython27D-8.1.1 \
-lvtkFiltersFlowPaths-8.1.1 \
-lvtkFiltersFlowPathsPython27D-8.1.1 \
-lvtkFiltersGeneral-8.1.1 \
-lvtkFiltersGeneralPython27D-8.1.1 \
-lvtkFiltersGeneric-8.1.1 \
-lvtkFiltersGenericPython27D-8.1.1 \
-lvtkFiltersGeometry-8.1.1 \
-lvtkFiltersGeometryPython27D-8.1.1 \
-lvtkFiltersHybrid-8.1.1 \
-lvtkFiltersHybridPython27D-8.1.1 \
-lvtkFiltersHyperTree-8.1.1 \
-lvtkFiltersHyperTreePython27D-8.1.1 \
-lvtkFiltersImaging-8.1.1 \
-lvtkFiltersImagingPython27D-8.1.1 \
-lvtkFiltersModeling-8.1.1 \
-lvtkFiltersModelingPython27D-8.1.1 \
-lvtkFiltersParallel-8.1.1 \
-lvtkFiltersParallelImaging-8.1.1 \
-lvtkFiltersParallelImagingPython27D-8.1.1 \
-lvtkFiltersParallelPython27D-8.1.1 \
-lvtkFiltersPoints-8.1.1 \
-lvtkFiltersPointsPython27D-8.1.1 \
-lvtkFiltersProgrammable-8.1.1 \
-lvtkFiltersProgrammablePython27D-8.1.1 \
-lvtkFiltersPython-8.1.1 \
-lvtkFiltersPythonPython27D-8.1.1 \
-lvtkFiltersSMP-8.1.1 \
-lvtkFiltersSMPPython27D-8.1.1 \
-lvtkFiltersSelection-8.1.1 \
-lvtkFiltersSelectionPython27D-8.1.1 \
-lvtkFiltersSources-8.1.1 \
-lvtkFiltersSourcesPython27D-8.1.1 \
-lvtkFiltersStatistics-8.1.1 \
-lvtkFiltersStatisticsPython27D-8.1.1 \
-lvtkFiltersTexture-8.1.1 \
-lvtkFiltersTexturePython27D-8.1.1 \
-lvtkFiltersTopology-8.1.1 \
-lvtkFiltersTopologyPython27D-8.1.1 \
-lvtkFiltersVerdict-8.1.1 \
-lvtkFiltersVerdictPython27D-8.1.1 \
-lvtkGUISupportQt-8.1.1 \
-lvtkGUISupportQtSQL-8.1.1 \
-lvtkGeovisCore-8.1.1 \
-lvtkGeovisCorePython27D-8.1.1 \
-lvtkIOAMR-8.1.1 \
-lvtkIOAMRPython27D-8.1.1 \
-lvtkIOCore-8.1.1 \
-lvtkIOCorePython27D-8.1.1 \
-lvtkIOEnSight-8.1.1 \
-lvtkIOEnSightPython27D-8.1.1 \
-lvtkIOExodus-8.1.1 \
-lvtkIOExodusPython27D-8.1.1 \
-lvtkIOExport-8.1.1 \
-lvtkIOExportOpenGL2-8.1.1 \
-lvtkIOExportOpenGL2Python27D-8.1.1 \
-lvtkIOExportPython27D-8.1.1 \
-lvtkIOGeometry-8.1.1 \
-lvtkIOGeometryPython27D-8.1.1 \
-lvtkIOImage-8.1.1 \
-lvtkIOImagePython27D-8.1.1 \
-lvtkIOImport-8.1.1 \
-lvtkIOImportPython27D-8.1.1 \
-lvtkIOInfovis-8.1.1 \
-lvtkIOInfovisPython27D-8.1.1 \
-lvtkIOLSDyna-8.1.1 \
-lvtkIOLSDynaPython27D-8.1.1 \
-lvtkIOLegacy-8.1.1 \
-lvtkIOLegacyPython27D-8.1.1 \
-lvtkIOMINC-8.1.1 \
-lvtkIOMINCPython27D-8.1.1 \
-lvtkIOMovie-8.1.1 \
-lvtkIOMoviePython27D-8.1.1 \
-lvtkIONetCDF-8.1.1 \
-lvtkIONetCDFPython27D-8.1.1 \
-lvtkIOPLY-8.1.1 \
-lvtkIOPLYPython27D-8.1.1 \
-lvtkIOParallel-8.1.1 \
-lvtkIOParallelPython27D-8.1.1 \
-lvtkIOParallelXML-8.1.1 \
-lvtkIOParallelXMLPython27D-8.1.1 \
-lvtkIOSQL-8.1.1 \
-lvtkIOSQLPython27D-8.1.1 \
-lvtkIOTecplotTable-8.1.1 \
-lvtkIOTecplotTablePython27D-8.1.1 \
-lvtkIOVideo-8.1.1 \
-lvtkIOVideoPython27D-8.1.1 \
-lvtkIOXML-8.1.1 \
-lvtkIOXMLParser-8.1.1 \
-lvtkIOXMLParserPython27D-8.1.1 \
-lvtkIOXMLPython27D-8.1.1 \
-lvtkImagingColor-8.1.1 \
-lvtkImagingColorPython27D-8.1.1 \
-lvtkImagingCore-8.1.1 \
-lvtkImagingCorePython27D-8.1.1 \
-lvtkImagingFourier-8.1.1 \
-lvtkImagingFourierPython27D-8.1.1 \
-lvtkImagingGeneral-8.1.1 \
-lvtkImagingGeneralPython27D-8.1.1 \
-lvtkImagingHybrid-8.1.1 \
-lvtkImagingHybridPython27D-8.1.1 \
-lvtkImagingMath-8.1.1 \
-lvtkImagingMathPython27D-8.1.1 \
-lvtkImagingMorphological-8.1.1 \
-lvtkImagingMorphologicalPython27D-8.1.1 \
-lvtkImagingSources-8.1.1 \
-lvtkImagingSourcesPython27D-8.1.1 \
-lvtkImagingStatistics-8.1.1 \
-lvtkImagingStatisticsPython27D-8.1.1 \
-lvtkImagingStencil-8.1.1 \
-lvtkImagingStencilPython27D-8.1.1 \
-lvtkInfovisBoostGraphAlgorithms-8.1.1 \
-lvtkInfovisBoostGraphAlgorithmsPython27D-8.1.1 \
-lvtkInfovisCore-8.1.1 \
-lvtkInfovisCorePython27D-8.1.1 \
-lvtkInfovisLayout-8.1.1 \
-lvtkInfovisLayoutPython27D-8.1.1 \
-lvtkInteractionImage-8.1.1 \
-lvtkInteractionImagePython27D-8.1.1 \
-lvtkInteractionStyle-8.1.1 \
-lvtkInteractionStylePython27D-8.1.1 \
-lvtkInteractionWidgets-8.1.1 \
-lvtkInteractionWidgetsPython27D-8.1.1 \
-lvtkParallelCore-8.1.1 \
-lvtkParallelCorePython27D-8.1.1 \
-lvtkRenderingAnnotation-8.1.1 \
-lvtkRenderingAnnotationPython27D-8.1.1 \
-lvtkRenderingContext2D-8.1.1 \
-lvtkRenderingContext2DPython27D-8.1.1 \
-lvtkRenderingContextOpenGL2-8.1.1 \
-lvtkRenderingContextOpenGL2Python27D-8.1.1 \
-lvtkRenderingCore-8.1.1 \
-lvtkRenderingCorePython27D-8.1.1 \
-lvtkRenderingFreeType-8.1.1 \
-lvtkRenderingFreeTypeFontConfig-8.1.1 \
-lvtkRenderingFreeTypePython27D-8.1.1 \
-lvtkRenderingGL2PSOpenGL2-8.1.1 \
-lvtkRenderingGL2PSOpenGL2Python27D-8.1.1 \
-lvtkRenderingImage-8.1.1 \
-lvtkRenderingImagePython27D-8.1.1 \
-lvtkRenderingLOD-8.1.1 \
-lvtkRenderingLODPython27D-8.1.1 \
-lvtkRenderingLabel-8.1.1 \
-lvtkRenderingLabelPython27D-8.1.1 \
-lvtkRenderingOpenGL2-8.1.1 \
-lvtkRenderingOpenGL2Python27D-8.1.1 \
-lvtkRenderingQt-8.1.1 \
-lvtkRenderingQtPython27D-8.1.1 \
-lvtkRenderingVolume-8.1.1 \
-lvtkRenderingVolumeOpenGL2-8.1.1 \
-lvtkRenderingVolumeOpenGL2Python27D-8.1.1 \
-lvtkRenderingVolumePython27D-8.1.1 \
-lvtkViewsContext2D-8.1.1 \
-lvtkViewsContext2DPython27D-8.1.1 \
-lvtkViewsCore-8.1.1 \
-lvtkViewsCorePython27D-8.1.1 \
-lvtkViewsInfovis-8.1.1 \
-lvtkViewsInfovisPython27D-8.1.1 \
-lvtkViewsQt-8.1.1 \
-lvtkWrappingPython27Core-8.1.1 \
-lvtkalglib-8.1.1 \
-lvtkexoIIc-8.1.1 \
-lvtkfreetype-8.1.1 \
-lvtkgl2ps-8.1.1 \
-lvtkglew-8.1.1 \
-lvtkjsoncpp-8.1.1 \
-lvtklibharu-8.1.1 \
-lvtklz4-8.1.1 \
-lvtkmetaio-8.1.1 \
-lvtknetcdfcpp-8.1.1 \
-lvtkoggtheora-8.1.1 \
-lvtkproj4-8.1.1 \
-lvtksqlite-8.1.1 \
-lvtksys-8.1.1 \
-lvtkverdict-8.1.1

LIBS += -L/usr/local/Cellar/boost/1.67.0_1/lib -lboost_date_time-mt \
-lboost_thread-mt \
-lboost_filesystem-mt \
-lboost_system-mt \
-lboost_iostreams-mt

LIBS += -L/usr/local/Cellar/flann/1.9.1_6/lib -lflann_cpp_s

LIBS += -L/usr/local/Cellar/qhull/2015.2/lib -lqhullstatic

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

一些需要注意的问题

这里各个平台不同,但是可能都会遇到一个HiDPI的问题。我的电脑是2015 Early的MacBook Pro Retina,开始遇到了外接非高分屏幕的时候,软件的自动缩放出现故障,导致除了VTK控件之外的所有控件都失控了。这个问题最开始我处理了一天,但是最后也没什么结果,中间我搜寻到了一篇Yale图形学相关研究者的文章:

这篇文章阐述了她是如何在Windows平台下解决HiDPI问题的,但是很可惜并不试用于macOS平台。后来又找到了Qt官方论坛的一个讨论,大意是希望VTK能够迁移到Qt新的基于OpenGL的控件平台,但是被开发者委婉的拒绝了,理由是目前够用,而且新款还在迭代开发不够稳定。。。所以这也解释了为什么在启动应用的时候会有一大堆的deprecated的飘红,看来这是一个不可调和的矛盾了。我尝试把qvtkWidget禁用后,界面果然恢复了正常,但是不可能不用这个vtk的控件啊!这时候就只有一个办法了,我们右键针对macOS平台打包好的app文件,会有一个『以低分辨率打开』的选项,这样处理完打开应用就不会出现缩放问题了,当然也得忍受模糊的界面了。

problem