I am trying to build the minimal Qt VTK app which is part of the official VTK examples (shown here). The C++ code for the app itself is mostly the same as specified via the link:
#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 <QDebug>
#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, vtkDataSetMapper* mapper,
vtkGenericOpenGLRenderWindow* window, std::mt19937& randEng);
} // namespace
int main(int argc, char* argv[])
{
QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());
QApplication app(argc, argv);
qDebug() << "VERSION" << qVersion();
// 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, vtkDataSetMapper* 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
The only real difference is that I’ve added the line qDebug() << "VERSION" << qVersion();
to indicate which version is actually used by the compiled executable.
The CMakelists.txt file has been heavily edited by me and looks like the following:
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
PROJECT(MinimalQtVTKApp)
find_package(VTK COMPONENTS
CommonCore
CommonDataModel
FiltersSources
GUISupportQt
InteractionStyle
RenderingContextOpenGL2
RenderingCore
RenderingFreeType
RenderingGL2PSOpenGL2
RenderingOpenGL2
GUISupportQt
RenderingQt
)
set(VTK_QT_VERSION 6)
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets OpenGLWidgets)
message (STATUS "VTK_VERSION: ${VTK_VERSION}, Qt Version: ${Qt${VTK_QT_VERSION}Widgets_VERSION}")
# Instruct CMake to run moc and uic automatically when needed.
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
# CMAKE_AUTOMOC in ON so the MOC headers will be automatically wrapped.
add_executable(MinimalQtVTKApp MACOSX_BUNDLE
MinimalQtVTKApp.cxx
)
target_link_libraries(MinimalQtVTKApp ${VTK_LIBRARIES} Qt6::Core Qt6::Gui Qt6::Widgets Qt6::OpenGLWidgets)
vtk_module_autoinit(
TARGETS MinimalQtVTKApp
MODULES ${VTK_LIBRARIES}
)
So basically, the CMake file finds VTK and all necessary, required packages, along with all required Qt6 packages, adds the executable and then links Qt and VTK to it.
Next, I created a build
directory, entered it and hit cmake ..
. This will lead to the following error message:
CMake Error: The INTERFACE_QT_MAJOR_VERSION property of "Qt6::Core" does not agree with the value of QT_MAJOR_VERSION already determined for "MinimalQtVTKApp".
I can built the application nonetheless, but it will rely on Qt5 then.
I am really confused by this error message and by the application using Qt5, because the file specifically tells CMake to use Qt6 instead of Qt5. Also, I am on Ubuntu 22.04 and using VTK version 9.1, but afaik this version already supports Qt6.
What might be the reason for the application displaying this error message? Is it even related to VTK at all? Or is there an error with my CMakeLists.txt?
Thanks in advance!