VTK+CTK+Qt5 配置与测试

VTK+CTK+Qt5 配置与测试

VTK+CTK+Qt5 配置与测试_第1张图片

fitsir关注

0.3722018.10.28 12:20:32字数 368阅读 5,727

VTK、CTK的编译安装

下载

  1. VTK源码地址:Gitlab或者Github
  2. CTK源码地址:Github
  3. CMake, 3.12.3
  4. git
  5. Qt 5.11.2
  6. 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 
//VTK includes
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

void vtk_without_qt();

int main() {
    std::cout << "Hello, World!" << std::endl;
    vtk_without_qt();
    return 0;
}

void vtk_without_qt(){
    auto cylinder = vtkSmartPointer::New();
    cylinder->SetHeight(3.0);
    cylinder->SetRadius(1.0);
    cylinder->SetResolution(10);
    auto cylinderMapper = vtkSmartPointer::New();
    cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
    auto cylinderActor = vtkSmartPointer::New();
    cylinderActor->SetMapper(cylinderMapper);
    auto renderer = vtkSmartPointer::New();
    renderer->AddActor(cylinderActor);
    renderer->SetBackground(0.1, 0.2, 0.4);
    auto renWin = vtkSmartPointer::New();
    renWin->AddRenderer(renderer);
    renWin->SetSize(300, 300);
    auto iren = vtkSmartPointer::New();
    iren->SetRenderWindow(renWin);
    auto style = vtkSmartPointer::New();
    iren->SetInteractorStyle(style);

    iren->Initialize();
    iren->Start();
}

运行效果

VTK+CTK+Qt5 配置与测试_第2张图片

vtk_without_qt.png

VTK+Qt5 测试

CMakeLists.txt

CMakeLists.txt只需添加Qt5相关的库

target_link_libraries(VTKTest
    ${VTK_LIBRARIES}
    ${Qt5Widgets_LIBRARIES}
    ${Qt5OpenGL_LIBRARIES})

main.cpp

#include 
//VTK includes
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
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::New();
    cylinder->SetHeight(3.0);
    cylinder->SetRadius(1.0);
    cylinder->SetResolution(10);
    auto cylinderMapper = vtkSmartPointer::New();
    cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
    auto cylinderActor = vtkSmartPointer::New();
    cylinderActor->SetMapper(cylinderMapper);
    auto renderer = vtkSmartPointer::New();
    renderer->AddActor(cylinderActor);
    renderer->SetBackground(0.1, 0.2, 0.4);
    auto renWin = vtkSmartPointer::New();
    renWin->AddRenderer(renderer);

    v.SetRenderWindow(renWin);
    w.show();

    return a.exec();
}

运行效果

VTK+CTK+Qt5 配置与测试_第3张图片

vtk_with_qt.png

VTK+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 
//VTK includes
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
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::New();
    cylinder->SetHeight(3.0);
    cylinder->SetRadius(1.0);
    cylinder->SetResolution(10);
    auto cylinderMapper = vtkSmartPointer::New();
    cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
    auto cylinderActor = vtkSmartPointer::New();
    cylinderActor->SetMapper(cylinderMapper);
    auto renderer = vtkSmartPointer::New();
    renderer->AddActor(cylinderActor);
    renderer->SetBackground(0.1, 0.2, 0.4);
    auto renWin = vtkSmartPointer::New();
    renWin->AddRenderer(renderer);

    v.renderWindow()->AddRenderer(renderer);
    w.show();

    return a.exec();
}

运行效果

VTK+CTK+Qt5 配置与测试_第4张图片

vtk_with_ctk_qt.png

VTK 机械臂控制

main.cpp

//VTK includes
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int vtk_arm_control(int argc, char* argv[]);
vtkSmartPointer 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 renderer;
vtkSmartPointer assembly[3];
vtkSmartPointer renWin;

int main(int argc, char* argv[]) {
    qDebug() << "Hello, World!";
    QSurfaceFormat::setDefaultFormat(QVTKOpenGLWidget::defaultFormat());
    renderer = vtkSmartPointer::New();
    renWin = vtkSmartPointer::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 filenames;
    filenames << path + FILE1          //1
              << path + FILE2
              << path + FILE3;
    vtkSmartPointer actor[3];
    for(int i = 0; i < filenames.size(); i++) {
        actor[i] = setupActor(filenames[i].toLatin1());
    }

    assembly[1] = vtkSmartPointer::New();
    assembly[0] = vtkSmartPointer::New();
    assembly[2] = vtkSmartPointer::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 setupActor(QString toolPath) {
    qDebug() << "setupActor";
    QFile file(toolPath);
    if(!file.exists()) {
        qDebug() << QString("STL file %1 is missing").arg(toolPath);
        return nullptr;
    }

    vtkSmartPointer actor = vtkSmartPointer::New();
    vtkSmartPointer reader = vtkSmartPointer::New();
    vtkSmartPointer mapper = vtkSmartPointer::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 camera = vtkSmartPointer::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 ground = vtkSmartPointer::New();
    vtkSmartPointer ground_plane = vtkSmartPointer::New();

    ground_plane->SetXResolution(50);
    ground_plane->SetYResolution(50);
    ground_plane->SetCenter(0, 0, 0);
    ground_plane->SetNormal(0, 0, 1);

    vtkSmartPointer ground_mapper = vtkSmartPointer::New();
    ground_mapper->SetInputConnection(ground_plane->GetOutputPort());
    ground->SetMapper(ground_mapper);
    ground->GetProperty()->SetRepresentationToWireframe();
    vtkSmartPointer ground_transform = vtkSmartPointer::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 axes = vtkSmartPointer::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();
}

运行效果

VTK+CTK+Qt5 配置与测试_第5张图片

arm_control_1.png

VTK+CTK+Qt5 配置与测试_第6张图片

arm_control_2.png

源码

coding

 

3人点赞

 

软件

 

你可能感兴趣的:(Qt)