VTK+CTK+Qt5 配置与测试
2018-10-28 本文已影响0人
fitsir
VTK、CTK的编译安装
下载
- VTK源码地址:Gitlab或者Github
- CTK源码地址:Github
- CMake, 3.12.3
- git
- Qt 5.11.2
- Windows: Visual Studio 2017, Mac: clang + make
编译
编译VTK
$ mkdir Libs
$ cd Libs
$ git clone https://gitlab.kitware.com/vtk/vtk.git
#注:Windows下使用最新版本,Mac下使用v8.0.1,不然总出现OpenGL错误,未解决
使用CMake-GUI配置,
-
Where is the source code
选择Libs/VTK
, -
Where to build the binaries
选择Libs/VTK-build
, -
CMAKE_INSTALL_PREFIX
选择Libs/VTK-install
-
VTK_Group_QT
勾选, -
VTK_QT_VERSION
选择5
, -
Qt5_DIR
选择Qt5安装目录下的5.11.2/lib/cmake/Qt5
目录, -
Windows下可勾选
Module_vtkGUISupportQtOpenGL
,Mac下勾选运行时会报错,不知道为什么 -
VTK_DEBUG_LEAKS
可勾选,程序运行完会提示是否有内存泄漏 -
取消勾选
BUILD_TEST
-
多次
configure
没有错误及红色提示之后Generate
编译工程, 安装
编译CTK
$ mkdir Libs
$ cd Libs
$ git clone https://github.com/commontk/CTK.git
使用CMake-GUI配置,
-
Where is the source code
选择Libs/CTK
, -
Where to build the binaries
选择Libs/CTK-build
, -
CMAKE_INSTALL_PREFIX
选择Libs/CTK-install
-
CTK_QT_VERSION
选择5
, -
Qt5_DIR
选择Qt5安装目录下的5.11.2/lib/cmake/Qt5
目录, - 勾选
CMAKE_BUILD_QTDESIGNER_PLUGINS
- 取消勾选
BUILD_TEST
- 多次
configure
没有错误及红色提示之后Generate
编译工程, 安装,注意,CTK安装需要在CTK-build
目录安装一次,然后在CTK-build/CTK-build
目录再安装一次
测试
VTK测试
CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
project(VTKTest)
set(CMAKE_CXX_STANDARD 14)
IF(APPLE)
SET(VTK_DIR "/Users/fitsir/Libs/VTK-install/lib/cmake/vtk-8.0")
SET(CTK_DIR "/Users/fitsir/Libs/CTK-install/lib/ctk-0.1/CMake")
ENDIF()
FIND_PACKAGE(VTK REQUIRED)
IF (VTK_FOUND)
MESSAGE(STATUS "VTK found.")
INCLUDE(${VTK_USE_FILE})
ENDIF()
FIND_PACKAGE(CTK REQUIRED)
IF(CTK_FOUND)
MESSAGE(STATUS "CTK found.")
INCLUDE(${CTK_USE_FILE})
ENDIF()
FIND_PACKAGE(Qt5 COMPONENTS Widgets OpenGL REQUIRED)
IF(Qt5_FOUND)
MESSAGE(STATUS "Qt5 found.")
ENDIF()
add_executable(VTKTest main.cpp)
target_link_libraries(VTKTest
${VTK_LIBRARIES})
main.cpp
#include <iostream>
//VTK includes
#include <vtkRenderWindow.h>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCylinderSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
void vtk_without_qt();
int main() {
std::cout << "Hello, World!" << std::endl;
vtk_without_qt();
return 0;
}
void vtk_without_qt(){
auto cylinder = vtkSmartPointer<vtkCylinderSource>::New();
cylinder->SetHeight(3.0);
cylinder->SetRadius(1.0);
cylinder->SetResolution(10);
auto cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
auto cylinderActor = vtkSmartPointer<vtkActor>::New();
cylinderActor->SetMapper(cylinderMapper);
auto renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(cylinderActor);
renderer->SetBackground(0.1, 0.2, 0.4);
auto renWin = vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer(renderer);
renWin->SetSize(300, 300);
auto iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
auto style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
iren->SetInteractorStyle(style);
iren->Initialize();
iren->Start();
}
运行效果
vtk_without_qt.pngVTK+Qt5 测试
CMakeLists.txt
CMakeLists.txt只需添加Qt5相关的库
target_link_libraries(VTKTest
${VTK_LIBRARIES}
${Qt5Widgets_LIBRARIES}
${Qt5OpenGL_LIBRARIES})
main.cpp
#include <iostream>
//VTK includes
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCylinderSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <QVTKOpenGLWidget.h>
#include <QApplication>
#include <QVBoxLayout>
#include <QSurfaceFormat>
int vtk_with_qt(int argc, char* argv[]);
int main(int argc, char* argv[]) {
std::cout << "Hello, World!" << std::endl;
QSurfaceFormat::setDefaultFormat(QVTKOpenGLWidget::defaultFormat());
return vtk_with_qt(argc, argv);
}
int vtk_with_qt(int argc, char* argv[]){
QApplication a(argc, argv);
QWidget w;// = new QWidget(0);
QVBoxLayout layout;// = new QVBoxLayout(0);
QVTKOpenGLWidget v;// = new QVTKOpenGLWidget();
v.setFixedSize(300, 300);
layout.addWidget(&v);
w.setLayout(&layout);
auto cylinder = vtkSmartPointer<vtkCylinderSource>::New();
cylinder->SetHeight(3.0);
cylinder->SetRadius(1.0);
cylinder->SetResolution(10);
auto cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
auto cylinderActor = vtkSmartPointer<vtkActor>::New();
cylinderActor->SetMapper(cylinderMapper);
auto renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(cylinderActor);
renderer->SetBackground(0.1, 0.2, 0.4);
auto renWin = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
renWin->AddRenderer(renderer);
v.SetRenderWindow(renWin);
w.show();
return a.exec();
}
运行效果
vtk_with_qt.pngVTK+CTK+Qt5测试
CMakeList.txt
#Qt5 需要添加CTK依赖的一些库
FIND_PACKAGE(Qt5 COMPONENTS Widgets OpenGL Xml Network REQUIRED)
target_link_libraries(VTKTest
${VTK_LIBRARIES}
${Qt5Widgets_LIBRARIES}
${Qt5OpenGL_LIBRARIES}
${CTK_LIBRARIES})
main.cpp
#include <iostream>
//VTK includes
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCylinderSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <QVTKOpenGLWidget.h>
#include <QApplication>
#include <QVBoxLayout>
#include <QSurfaceFormat>
#include <ctkVTKRenderView.h>
#include <ctkSliderWidget.h>
int vtk_with_ctk_qt(int argc, char* argv[]);
int main(int argc, char* argv[]) {
std::cout << "Hello, World!" << std::endl;
QSurfaceFormat::setDefaultFormat(QVTKOpenGLWidget::defaultFormat());
return vtk_with_ctk_qt(argc, argv);
}
int vtk_with_ctk_qt(int argc, char* argv[]){
QApplication a(argc, argv);
QWidget w;// = new QWidget(0);
QVBoxLayout layout;// = new QVBoxLayout(0);
ctkVTKRenderView v;// = new QVTKOpenGLWidget();
v.setFixedSize(300, 300);
layout.addWidget(&v);
ctkSliderWidget s;
s.setRange(0, 100);
layout.addWidget(&s);
w.setLayout(&layout);
auto cylinder = vtkSmartPointer<vtkCylinderSource>::New();
cylinder->SetHeight(3.0);
cylinder->SetRadius(1.0);
cylinder->SetResolution(10);
auto cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
auto cylinderActor = vtkSmartPointer<vtkActor>::New();
cylinderActor->SetMapper(cylinderMapper);
auto renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(cylinderActor);
renderer->SetBackground(0.1, 0.2, 0.4);
auto renWin = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
renWin->AddRenderer(renderer);
v.renderWindow()->AddRenderer(renderer);
w.show();
return a.exec();
}
运行效果
vtk_with_ctk_qt.pngVTK 机械臂控制
main.cpp
//VTK includes
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkLODActor.h>
#include <vtkAssembly.h>
#include <vtkSTLReader.h>
#include <vtkProperty.h>
#include <vtkCamera.h>
#include <vtkPlaneSource.h>
#include <vtkTransform.h>
#include <vtkAxesActor.h>
#include <vtkCaptionActor2D.h>
#include <QVTKOpenGLWidget.h>
#include <QApplication>
#include <QVBoxLayout>
#include <QSurfaceFormat>
#include <QString>
#include <QFile>
#include <QDebug>
#include <QLineEdit>
#include <ctkSliderWidget.h>
int vtk_arm_control(int argc, char* argv[]);
vtkSmartPointer<vtkLODActor> setupActor(QString toolPath);
void setGround();
void setAxes();
void setAssembly();
void valueChanged1(double value);
void valueChanged2(double value);
void setCamera();
#define FILE1 "/A1.STL"
#define FILE2 "/A2.STL"
#define FILE3 "/A3.STL"
vtkSmartPointer<vtkRenderer> renderer;
vtkSmartPointer<vtkAssembly> assembly[3];
vtkSmartPointer<vtkGenericOpenGLRenderWindow> renWin;
int main(int argc, char* argv[]) {
qDebug() << "Hello, World!";
QSurfaceFormat::setDefaultFormat(QVTKOpenGLWidget::defaultFormat());
renderer = vtkSmartPointer<vtkRenderer>::New();
renWin = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
return vtk_arm_control(argc, argv);
}
int vtk_arm_control(int argc, char* argv[]){
QApplication a(argc, argv);
QWidget window;
window.setMinimumSize(400, 400);
QVBoxLayout layout;
QVTKOpenGLWidget view;
ctkSliderWidget slider1, slider2;
slider1.setMinimum(-180);
slider1.setMaximum(180);
slider2.setMinimum(-180);
slider2.setMaximum(180);
layout.addWidget(&view);
layout.addWidget(&slider1);
layout.addWidget(&slider2);
QObject::connect(&slider1, &ctkSliderWidget::valueChanged, &valueChanged1);
QObject::connect(&slider2, &ctkSliderWidget::valueChanged, &valueChanged2);
window.setLayout(&layout);
QString path = "/Users/fitsir/P/VTKTest/stl";
QList<QString> filenames;
filenames << path + FILE1 //1
<< path + FILE2
<< path + FILE3;
vtkSmartPointer<vtkLODActor> actor[3];
for(int i = 0; i < filenames.size(); i++) {
actor[i] = setupActor(filenames[i].toLatin1());
}
assembly[1] = vtkSmartPointer<vtkAssembly>::New();
assembly[0] = vtkSmartPointer<vtkAssembly>::New();
assembly[2] = vtkSmartPointer<vtkAssembly>::New();
assembly[2]->AddPart(actor[2]);
assembly[2]->SetOrigin(350, 0, 705);
assembly[1]->AddPart(actor[1]);
assembly[1]->AddPart(assembly[2]);
assembly[1]->SetOrigin(0, 0, 0);
assembly[0]->AddPart(actor[0]);
assembly[0]->AddPart(assembly[1]);
assembly[0]->SetOrigin(0, 0, 0);// # This is the point about which all rotations take place
renderer->AddActor(assembly[0]);
renWin->AddRenderer(renderer);
setAxes();
setGround();
renderer->SetBackground(.2, .2, .2);
setCamera();
renderer->ResetCameraClippingRange();
view.SetRenderWindow(renWin);
window.show();
return a.exec();
}
vtkSmartPointer<vtkLODActor> setupActor(QString toolPath) {
qDebug() << "setupActor";
QFile file(toolPath);
if(!file.exists()) {
qDebug() << QString("STL file %1 is missing").arg(toolPath);
return nullptr;
}
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
reader->SetFileName(toolPath.toLatin1());
reader->Update();
mapper->SetInputConnection(reader->GetOutputPort());
actor->SetMapper(mapper);
double r = vtkMath::Random(.4, 1.0);
double g = vtkMath::Random(.4, 1.0);
double b = vtkMath::Random(.4, 1.0);
actor->GetProperty()->SetDiffuseColor(r, g, b);
actor->GetProperty()->SetDiffuse(.8);
actor->GetProperty()->SetSpecular(.5);
actor->GetProperty()->SetSpecularColor(1.0, 1.0, 1.0);
actor->GetProperty()->SetSpecularPower(30.0);
return actor;
}
void setCamera() {
qDebug() << "setCamera";
if(renderer == nullptr) {
qDebug() << "Renderer is nullptr";
return;
}
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
camera->SetFocalPoint(600, 0, 1300);
camera->SetPosition(700, 2200, 1500);
camera->Zoom(0.4);
camera->SetViewUp(0, 0, 1);
renderer->SetActiveCamera(camera);
}
void setGround() {
qDebug() << "setGround";
vtkSmartPointer<vtkActor> ground = vtkSmartPointer<vtkActor>::New();
vtkSmartPointer<vtkPlaneSource> ground_plane = vtkSmartPointer<vtkPlaneSource>::New();
ground_plane->SetXResolution(50);
ground_plane->SetYResolution(50);
ground_plane->SetCenter(0, 0, 0);
ground_plane->SetNormal(0, 0, 1);
vtkSmartPointer<vtkPolyDataMapper> ground_mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
ground_mapper->SetInputConnection(ground_plane->GetOutputPort());
ground->SetMapper(ground_mapper);
ground->GetProperty()->SetRepresentationToWireframe();
vtkSmartPointer<vtkTransform> ground_transform = vtkSmartPointer<vtkTransform>::New();
ground_transform->Scale(4000, 4000, 1);
ground->SetUserTransform(ground_transform);
renderer->AddActor(ground);
}
void setAxes() {
qDebug() << "setAxes";
if(renderer == nullptr) {
qDebug() << "Renderer is nullptr";
return;
}
vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();
axes->SetTotalLength(1000, 1000, 1200); // # Set the total length of the axes in 3 dimensions
axes->SetShaftType(1);
axes->SetCylinderRadius(0.02);
axes->GetXAxisCaptionActor2D()->SetWidth(0.04);
axes->GetYAxisCaptionActor2D()->SetWidth(0.04);
axes->GetZAxisCaptionActor2D()->SetWidth(0.04);
renderer->AddActor(axes);
}
void valueChanged1(double value) {
assembly[1]->SetOrientation(0, 0, -value);
renWin->Render();
}
void valueChanged2(double value) {
assembly[2]->SetOrientation(0, -value, 0);
renWin->Render();
}