QT學習VTK序列:Oriented Cylinder

學習VTK繪製方向圓柱體

/*
 * ModuleName: 模塊名稱
 * Description:
 * 參考代碼:https://lorensen.github.io/VTKExamples/site/Cxx/GeometricObjects/OrientedCylinder/
 * Author: hsw
 * Date: 2020-03-15
 *
*/

// QT
#include <QMainWindow>
#include <QDebug>

// VTK
#include <vtkActor.h>
#include <vtkCylinderSource.h>
#include <vtkMath.h>
#include <vtkMinimalStandardRandomSequence.h>
#include <vtkNamedColors.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkAutoInit.h>

// C++
#include <array>

namespace Ui {
class MainWindow;
}

VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingContextOpenGL2);
VTK_MODULE_INIT(vtkRenderingFreeType);

#define USER_MATRIX

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    Ui::MainWindow *ui;
private:

};

 

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    vtkSmartPointer<vtkNamedColors> colors =
            vtkSmartPointer<vtkNamedColors>::New();

    // Set the background color.
    std::array<unsigned char , 4> bkg{{26, 51, 77, 255}};
    colors->SetColor("BkgColor", bkg.data());


    // Create a cylinder.
    // Cylinder height vector is (0,1,0).
    // Cylinder center is in the middle of the cylinder
    vtkSmartPointer<vtkCylinderSource> cylinderSource =
            vtkSmartPointer<vtkCylinderSource>::New();
    cylinderSource->SetResolution(15);

    // Generate a random start and end point
    double startPoint[3];
    double endPoint[3];
    vtkSmartPointer<vtkMinimalStandardRandomSequence> rng =
            vtkSmartPointer<vtkMinimalStandardRandomSequence>::New();
    rng->SetSeed(8775070); // For testing.
    for (auto i = 0; i < 3; ++i)
    {
        rng->Next();
        startPoint[i] = rng->GetRangeValue(-10, 10);
        rng->Next();
        endPoint[i] = rng->GetRangeValue(-10, 10);
    }

    // Compute a basis
    double normalizedX[3];
    double normalizedY[3];
    double normalizedZ[3];

    // The X axis is a vector from start to end
    vtkMath::Subtract(endPoint, startPoint, normalizedX);
    double length = vtkMath::Norm(normalizedX);
    vtkMath::Normalize(normalizedX);

    // The Z axis is an arbitrary vector cross X
    double arbitrary[3];
    for (auto i = 0; i < 3; ++i)
    {
        rng->Next();
        arbitrary[i] = rng->GetRangeValue(-10, 10);
    }
    vtkMath::Cross(normalizedX, arbitrary, normalizedZ);
    vtkMath::Normalize(normalizedZ);

    // The Y axis is Z cross X
    vtkMath::Cross(normalizedZ, normalizedX, normalizedY);
    vtkSmartPointer<vtkMatrix4x4> matrix =
            vtkSmartPointer<vtkMatrix4x4>::New();

    // Create the direction cosine matrix
    matrix->Identity();
    for (unsigned int i = 0; i < 3; i++)
    {
        matrix->SetElement(i, 0, normalizedX[i]);
        matrix->SetElement(i, 1, normalizedY[i]);
        matrix->SetElement(i, 2, normalizedZ[i]);
    }

    // Apply the transforms
    vtkSmartPointer<vtkTransform> transform =
            vtkSmartPointer<vtkTransform>::New();
    transform->Translate(startPoint);   // translate to starting point
    transform->Concatenate(matrix);     // apply direction cosines
    transform->RotateZ(-90.0);          // align cylinder to x axis
    transform->Scale(1.0, length, 1.0); // scale along the height vector
    transform->Translate(0, .5, 0);     // translate to start of cylinder

    // Transform the polydata
    vtkSmartPointer<vtkTransformPolyDataFilter> transformPD =
            vtkSmartPointer<vtkTransformPolyDataFilter>::New();
    transformPD->SetTransform(transform);
    transformPD->SetInputConnection(cylinderSource->GetOutputPort());

    //Create a mapper and actor for the cylinder
    vtkSmartPointer<vtkPolyDataMapper> mapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    vtkSmartPointer<vtkActor> actor =
            vtkSmartPointer<vtkActor>::New();
#ifdef USER_MATRIX
    mapper->SetInputConnection(cylinderSource->GetOutputPort());
    actor->SetUserMatrix(transform->GetMatrix());
#else
    mapper->SetInputConnection(transformPD->GetOutputPort());
#endif
    actor->SetMapper(mapper);
    actor->GetProperty()->SetColor(colors->GetColor3d("Cyan").GetData());

    // Create spheres for start and end point
    vtkSmartPointer<vtkSphereSource> sphereStartSource =
            vtkSmartPointer<vtkSphereSource>::New();
    sphereStartSource->SetCenter(startPoint);
    sphereStartSource->SetRadius(0.8);
    vtkSmartPointer<vtkPolyDataMapper> sphereStartMapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    sphereStartMapper->SetInputConnection(sphereStartSource->GetOutputPort());
    vtkSmartPointer<vtkActor> sphereStart =
            vtkSmartPointer<vtkActor>::New();
    sphereStart->SetMapper(sphereStartMapper);
    sphereStart->GetProperty()->SetColor(colors->GetColor3d("Yellow").GetData());

    vtkSmartPointer<vtkSphereSource> sphereEndSource =
            vtkSmartPointer<vtkSphereSource>::New();
    sphereEndSource->SetCenter(endPoint);
    sphereEndSource->SetRadius(0.8);
    vtkSmartPointer<vtkPolyDataMapper> sphereEndMapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    sphereEndMapper->SetInputConnection(sphereEndSource->GetOutputPort());
    vtkSmartPointer<vtkActor> sphereEnd =
            vtkSmartPointer<vtkActor>::New();
    sphereEnd->SetMapper(sphereEndMapper);
    sphereEnd->GetProperty()->SetColor(colors->GetColor3d("Magenta").GetData());

    //Create a renderer, render window, and interactor
    vtkSmartPointer<vtkRenderer> renderer =
            vtkSmartPointer<vtkRenderer>::New();

    //Add the actor to the scene
    renderer->AddActor(actor);
    renderer->AddActor(sphereStart);
    renderer->AddActor(sphereEnd);
    renderer->SetBackground(colors->GetColor3d("BkgColor").GetData());

    // vtkRenderWindow
    ui->qvtkWidget->GetRenderWindow()->AddRenderer(renderer);
    ui->qvtkWidget->GetRenderWindow()->SetWindowName("Oriented Cylinder");
}

MainWindow::~MainWindow()
{
    delete ui;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章