美文网首页
VTK+CTK+Qt5 配置与测试

VTK+CTK+Qt5 配置与测试

作者: fitsir | 来源:发表于2018-10-28 12:20 被阅读0次

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

    相关文章

      网友评论

          本文标题:VTK+CTK+Qt5 配置与测试

          本文链接:https://www.haomeiwen.com/subject/krdptqtx.html