VTK & Qt: rendering issues when drawing thick lines

Hello,

We are using Qt 5.15.7 and VTK 9.2.2. After the update from VTK 8.2.0, we started to encounter strange line-rendering issues that did not occur before. These issues apply to all lines that are rendered with thickness > 1. What happens is that the lines have a strange thickness (larger than the expected one) that is changing depending on the point of view. Also, the lines are showing artifacts when looking along them.

Examples:

Blue line with a thickness of 2.0

The same line after rotating the camera (while preserving the same distance to the line):

Two lines rendered: a blue line with 2.0 thickness and pink line with 4.0 thickness. Here you can also notice that the line width seems to somehow take line’s distance to the camera into account.

If you are looking along the line (i.e., position the camera on the line and look in the same direction), you may see following artifacts:

Remarks: These issues influence all lines that are rendered in our Qt application. It was verified on different hardware/resolutions/graphics cards. However, our C# application (using the same VTK codebase but without Qt) seems to work well. Similarly, we have other applications that use the combination of the same-versioned Qt & VTK as we do and their line-rendering works nicely.
Thus, there might be some issue in our VTK-related codebase that might have popped up after the update to VTK 9.2.2, yet we fail to identify the root cause.

We would be grateful for any ideas guiding us in the right direction.

FYI @Charles_Gueunet

@dkutak : the simplest way forward is to bisect to find the offending commit.

Thanks for the quick reply and yep, we tried that and this lead us to point of VTK update to 9.2.2. Since this git history approach did not help us much (i.e., we did not find a specific code change that seems to cause this), we also tried to downgrade our current codebase back to VTK 8.2.0 (there were barely any changes required apart from the VTK itself), and the lines started to work again.
Thus, it really feels like that the code does something that was well-accepted in 8.2.0 (although it might be potentially incorrect code [aka undefined behavior] but 8.2.0 may “deal with it”) but it stops working in 9.2.2. But that is just a guess to be honest.
We tried many different solutions how to tackle the issue, including running the application through RenderDoc and checking the API, but our theories were so far wrong and did not lead to solution.
One observation is that the lines with thickness > 1 are apparently rendered using some VTK solution (i.e., not via driver – please correct me if I am wrong), so the cause might be related to this. We also tried to render lines as tubes (using the RenderLinesAsTubes call) but the behavior was the same.

I mean bisect VTK

Ah, thanks and sorry for the misunderstanding. Yes, that might be the way to go now. We were now jumping between combinations of VTK 9.2.2 & VTK 8.2.0 + Qt 5.12.6 & Qt 5.15.7 (suspecting that Qt might have had some influence) and given the outcomes, we will probably have to bisect the VTK more properly.

@dkutak What OS and graphics drivers are you running this on?

@sankhesh I am running Windows 10 with Intel Iris Xe Graphics (driver v. 31.0.101.4887).
The problem occurred also on another Windows 10 computer with AMD Ryzen 7 PRO 5850U with Radeon Graphics (driver v. 27.20.14501.45003).
We were able to reproduce it also on Windows 11 with AMD Ryzen GPUs.

https://gitlab.kitware.com/paraview/paraview/-/issues/22594

https://discourse.paraview.org/t/cell-values-partly-disappear-when-editing-width-on-mac/11666

https://gitlab.kitware.com/paraview/paraview/-/issues/21832

For us, using Vtk 9.2.6 + Qt 6.5.3 and 6.6.3, the Windows and Linux machines do not show this behavior. MacOS on INTEL does not show the behavior. MacOS on ARM64 does show the behavior.

You might try a slightly newer version of Vtk (9.2.6) and maybe the Windows/Linux fixes you need are in there.

@dkutak Do you see similar behavior when it is just a vtk window? i.e. without Qt?

I have not been able to test that scenario.

In our case, our C# application (not using Qt widget) seems to behave well (despite generally using the same VTK codebase).
After further exploration, it seems that the issue is related to transition from QVTKWidget to QVTKOpenGLNativeWidget. I have been able to reproduce the problem using VTK 9.0.0.rc1 when we used QVTKOpenGLNativeWidget but changing our viewer to derive from QVTKWidget instead helped. Thus, there appears to be some relation to the changes related to Qt widgets, windows or so.

Thank you for the information and links. I will take a closer look at it.
I initially tried also VTK 9.3 and it did not seem to help.

Are you setting up the Qt surface format as described here: VTK: QVTKOpenGLNativeWidget Class Reference ?

Yes, we are doing exactly the same (I also suspected something may have gone wrong here but it seems ok).

Hello all,

We further examined the issue (the root cause is still unknown since the behavior seems to be triggered by the move from QVTKWidget to QVTKOpenGLNativeWidget) and managed to create a minimalistic example reproducing our problem. This example consists of a simple VTK (9.2.2) widget rendered within a Qt (5.15.7) application/window. The VTK scene contains a line and a cube (the cube is just for reference and does not seem to influence the line rendering behavior).

We made this example available for download:

  • Source code: contains two folders – VS 2022 solution and necessary Qt/VTK libraries. It should be possible to build the code [prepared for x64 & Release] by extracting the archive and building the solution.
  • Build: Windows x64 release build of the demo application (shown on images below). To execute, run QtVtkLineTest.exe file.

We are also posting the most important source codes here:

main.cpp
#include "QtVtkLineTest.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QSurfaceFormat::setDefaultFormat(QVTKOpenGLNativeWidget::defaultFormat());
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QApplication a(argc, argv);
    QtVtkLineTest w;
    w.show();
    return a.exec();
}
QtVtkLineTest.h
#pragma once

#include <QVTKOpenGLNativeWidget.h>

#include <QtWidgets/QMainWindow>
#include "ui_QtVtkLineTest.h"

class QtVtkLineTest : public QMainWindow
{
    Q_OBJECT

public:
    QtVtkLineTest(QWidget *parent = nullptr);
    ~QtVtkLineTest();

private:
    void add_line(vtkRenderer* renderer);
    void add_cube(vtkRenderer* renderer);

    Ui::QtVtkLineTestClass ui;
    QVTKOpenGLNativeWidget* vtkWidget;
};
QtVtkLineTest.cpp
#include "QtVtkLineTest.h"

#include <vtkActor.h>
#include <vtkCellArray.h>
#include <vtkLine.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkOpenGLState.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkVersion.h>
#include <vtkCubeSource.h>
#include <vtkLineSource.h>

QtVtkLineTest::QtVtkLineTest(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    setStyleSheet("background-color: #fffee0;");
    setWindowFlags(Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);

    QString versionInfo;
    versionInfo.append("VTK version: ");
    versionInfo.append(vtkVersion::GetVTKVersion());
    versionInfo.append(" | Qt version: ");
    versionInfo.append(QT_VERSION_STR);

    ui.versionInfo->setText(versionInfo);

    // Window & widget init
    vtkNew<vtkGenericOpenGLRenderWindow> renderWindow;
    vtkNew<vtkRenderer> renderer;
    renderer->SetBackground(0.9, 0.9, 0.9);
    renderWindow->AddRenderer(renderer);

    vtkWidget = new QVTKOpenGLNativeWidget(this);
    vtkWidget->setRenderWindow(renderWindow);
    ui.vtkWidgetLayout->addWidget(vtkWidget);

    // Objects creation
    add_line(renderer);
    add_cube(renderer);
}

QtVtkLineTest::~QtVtkLineTest()
{ }

void QtVtkLineTest::add_line(vtkRenderer* renderer)
{
    vtkNew<vtkLineSource> line;
    line->SetPoint1(0, 0, 0);
    line->SetPoint2(100, 200, 400);

    vtkNew<vtkNamedColors> colors;

    vtkNew<vtkPolyDataMapper> mapper;
    mapper->SetInputConnection(line->GetOutputPort());

    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);
    actor->GetProperty()->SetLineWidth(2);
    actor->GetProperty()->SetPointSize(2);
    actor->GetProperty()->SetColor(colors->GetColor3d("Crimson").GetData());

    renderer->AddActor(actor);
}

void QtVtkLineTest::add_cube(vtkRenderer* renderer)
{
    vtkNew<vtkCubeSource> cube;
    cube->SetXLength(12);
    cube->SetYLength(18);
    cube->SetZLength(32);
    cube->SetCenter(0, 64, 0);
    cube->Update();

    vtkNew<vtkNamedColors> colors;

    vtkNew<vtkPolyDataMapper> cubeMapper;
    cubeMapper->SetInputData(cube->GetOutput());

    vtkNew<vtkActor> cubeActor;
    cubeActor->SetMapper(cubeMapper);
    cubeActor->GetProperty()->SetColor(colors->GetColor3d("Banana").GetData());

    renderer->AddActor(cubeActor);
}

#include "QtVtkLineTest.moc"

In our case (tested on multiple Windows devices), the two-pixel line shows strange behavior when previewed from different perspectives and distances – you can see some examples of the rendering artifacts on the image below.

Everything seems to work well with one-pixel lines. Thus, we assume there might be some conflict between Qt and VTK’s geometry shader-based wide line rendering.

We would be very glad for any ideas how to tackle this problem. Newer VTK versions did not seem to help.

Are you seeing this on Windows and/or Linux? we only saw it on MacOS.

Yes, we can reproduce the minimal example above on various Windows devices.