VTK+CTK+Qt5 配置与测试

2018-10-28  本文已影响0人  fitsir

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配置,

编译CTK

$ mkdir Libs
$ cd Libs
$ git clone https://github.com/commontk/CTK.git 

使用CMake-GUI配置,

测试

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.png

VTK+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.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 <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.png

VTK 机械臂控制

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();
}

运行效果

arm_control_1.png arm_control_2.png

源码

coding

上一篇下一篇

猜你喜欢

热点阅读