One: Introduction
VTK: is an open source software library for 3D computer graphics, image processing, data visualization, and scientific visualization. VTK provides a wealth of basic algorithms and data structures, including points, lines, polygons, 2D and 3D images, volume rendering, etc., as well as many advanced algorithms, such as surface reconstruction, fluid dynamics simulation, fitting and interpolation, image segmentation and imaging processing etc.
QT: Provides a complete set of libraries, including GUI, network, database, XML, Bluetooth, multimedia, OpenGL, etc., which can be used to write desktop, mobile device, embedded and real-time applications. Qt's code portability is very good, developers can write a code, compile and run on Windows, Linux, Mac OS and other platforms without changing the code. Qt is characterized by easy learning and use, rich documentation and examples, rich third-party library support, fast development speed, efficient code generation, beautiful and easy-to-use interface, and is a very popular cross-platform development framework.
Two: environment
Win10
VS2019
VTK9.0.3 https://vtk.org/files/release/9.0/VTK-9.0.3.tar.gz
QT5.14.2 https://download.qt.io/archive/qt/5.14/5.14.2/
After the download is complete, VTK will be decompressed, and QT will be installed.
Three: Install and compile
1. Create a folder first
Create two folders, build and install, under the VTK directory. build stores compilation results and executable files, and install stores compiled include and lib.
2. cmake settings
(1) Select the location where vtk was decompressed just now. (2) Select the build folder you just created. (3) configure Among them, Advanced needs to be checked, and here cmake is checked by default.
(1) Select vs2019 (2) Select x64 (3) Finish
wait for it to finish
There will be a bunch of red warnings after the end. There are some areas that need modification. CMAKE_INSTALL_PREFIX needs to change the location to the previously created install folder.
VTK_BUILD_EXAMPLES needs to be checked
Search QT and change all Values to YES
Next press Configure. A red warning will also pop up, and the QT location will not be found. Fill in the positions below with the previously installed QT positions accordingly. (QT5.14.2 does not have a VS2019 folder, and it is the same to replace it with VS2017)
Press Configure again and all will pass without red warnings. Press Generate again and it will be generated as shown in the figure below.
3. compile
Find VTK.sln in the previously built build folder and open it.
Open the interface as follows, adjust release or debug. Find ALL_BUILD right-click - build.
After the previous step is over, find INSTALL and right click to generate
After the installation is complete, the following files will be generated in the install folder.
Four: VS configuration QT
1. Create a new C++ project, then search for QT in Extensions--Manage Extensions, download and install Qt Visual Studio Tools.
2. After the installation is complete, open the extension--Qt VS Tools--Qt Versions
3. Fill in the location where Qt was installed before
The above operation VS configuration QT is completed.
Five: Example
1. Create a new VS project
At this time, searching for QT will pop up the corresponding QT project that can be created.
Here we can directly select DEBUG to enter, and then adjust to Release through VS later.
After the newly created project enters, there are already some basic codes, which can be run directly. You will get the following window.
2. Configure the VTK environment
VC++ directory--include directory
VC++ directory--library directory
linker --input --additional dependencies
Debugging--environment (the environment I added here did not work for some reason, so I copied all the dlls under the bin to the release folder of the newly created QT project).
The VTK environment configuration is complete.
3. Test example
Official website classic example
#include <QVTKOpenGLNativeWidget.h>
#include <vtkActor.h>
#include <vtkDataSetMapper.h>
#include <vtkDoubleArray.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkPointData.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <QApplication>
#include <QDockWidget>
#include <QGridLayout>
#include <QLabel>
#include <QMainWindow>
#include <QPointer>
#include <QPushButton>
#include <QVBoxLayout>
#include <cmath>
#include <cstdlib>
#include <random>
namespace {
/**
* Deform the sphere source using a random amplitude and modes and render it in
* the window
*
* @param sphere the original sphere source
* @param mapper the mapper for the scene
* @param window the window to render to
* @param randEng the random number generator engine
*/
void Randomize(vtkSphereSource* sphere, vtkMapper* mapper,
vtkGenericOpenGLRenderWindow* window, std::mt19937& randEng);
} // namespace
int main(int argc, char* argv[])
{
QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());
QApplication app(argc, argv);
// main window
QMainWindow mainWindow;
mainWindow.resize(1200, 900);
// control area
QDockWidget controlDock;
mainWindow.addDockWidget(Qt::LeftDockWidgetArea, &controlDock);
QLabel controlDockTitle("Control Dock");
controlDockTitle.setMargin(20);
controlDock.setTitleBarWidget(&controlDockTitle);
QPointer<QVBoxLayout> dockLayout = new QVBoxLayout();
QWidget layoutContainer;
layoutContainer.setLayout(dockLayout);
controlDock.setWidget(&layoutContainer);
QPushButton randomizeButton;
randomizeButton.setText("Randomize");
dockLayout->addWidget(&randomizeButton);
// render area
QPointer<QVTKOpenGLNativeWidget> vtkRenderWidget =
new QVTKOpenGLNativeWidget();
mainWindow.setCentralWidget(vtkRenderWidget);
// VTK part
vtkNew<vtkGenericOpenGLRenderWindow> window;
vtkRenderWidget->setRenderWindow(window.Get());
vtkNew<vtkSphereSource> sphere;
sphere->SetRadius(1.0);
sphere->SetThetaResolution(100);
sphere->SetPhiResolution(100);
vtkNew<vtkDataSetMapper> mapper;
mapper->SetInputConnection(sphere->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
actor->GetProperty()->SetEdgeVisibility(true);
actor->GetProperty()->SetRepresentationToSurface();
vtkNew<vtkRenderer> renderer;
renderer->AddActor(actor);
window->AddRenderer(renderer);
// setup initial status
std::mt19937 randEng(0);
::Randomize(sphere, mapper, window, randEng);
// connect the buttons
QObject::connect(&randomizeButton, &QPushButton::released,
[&]() { ::Randomize(sphere, mapper, window, randEng); });
mainWindow.show();
return app.exec();
}
namespace {
void Randomize(vtkSphereSource* sphere, vtkMapper* mapper,
vtkGenericOpenGLRenderWindow* window, std::mt19937& randEng)
{
// generate randomness
double randAmp = 0.2 + ((randEng() % 1000) / 1000.0) * 0.2;
double randThetaFreq = 1.0 + (randEng() % 9);
double randPhiFreq = 1.0 + (randEng() % 9);
// extract and prepare data
sphere->Update();
vtkSmartPointer<vtkPolyData> newSphere;
newSphere.TakeReference(sphere->GetOutput()->NewInstance());
newSphere->DeepCopy(sphere->GetOutput());
vtkNew<vtkDoubleArray> height;
height->SetName("Height");
height->SetNumberOfComponents(1);
height->SetNumberOfTuples(newSphere->GetNumberOfPoints());
newSphere->GetPointData()->AddArray(height);
// deform the sphere
for (int iP = 0; iP < newSphere->GetNumberOfPoints(); iP++)
{
double pt[3] = {0.0};
newSphere->GetPoint(iP, pt);
double theta = std::atan2(pt[1], pt[0]);
double phi =
std::atan2(pt[2], std::sqrt(std::pow(pt[0], 2) + std::pow(pt[1], 2)));
double thisAmp =
randAmp * std::cos(randThetaFreq * theta) * std::sin(randPhiFreq * phi);
height->SetValue(iP, thisAmp);
pt[0] += thisAmp * std::cos(theta) * std::cos(phi);
pt[1] += thisAmp * std::sin(theta) * std::cos(phi);
pt[2] += thisAmp * std::sin(phi);
newSphere->GetPoints()->SetPoint(iP, pt);
}
newSphere->GetPointData()->SetScalars(height);
// reconfigure the pipeline to take the new deformed sphere
mapper->SetInputDataObject(newSphere);
mapper->SetScalarModeToUsePointData();
mapper->ColorByArrayComponent("Height", 0);
window->Render();
}
} // namespace