For more context, here is the program I am using to test my VTK/QT installation.
Boilerplate QT startup code:
#include "mainwindow.h"
#include <vtkAutoInit.h>
#include <QApplication>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
int main( int argc, char ** argv )
{
QApplication qtapplication( argc, argv );
MainWindow mw;
mw.show();
return qtapplication.exec();
}
Very simple QT form handler. The form simply consists of a button ‘drawSphere_button’ and a render window widget ‘openGLWidget’ in whichever flavour of QVTKOpenGL…Widget I’ve been testing.
The constructor simply initialises the user interface and sets up the render window.
The function onDrawSphereClick() adds a new sphere to a 3D stack of spheres on each button press and changes the background colour, stepping from red through to green.
#include <mainwindow.h>
#include "ui_MainWindow.h"
#include <vtkspheresource.h>
#include <vtkactor.h>
#include <vtkpolydataMapper.h>
#include <vtkRenderer.h>
#include <vtkGenericOpenGLRenderWindow.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow( parent )
{
ui = new Ui::MainWindow;
ui->setupUi( this );
mRenderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
mRenderer = vtkSmartPointer<vtkRenderer>::New();
mInteractor = vtkSmartPointer<QVTKInteractor>::New();
mInteractorStyle = vtkSmartPointer<vtkInteractorStyle>::New();
mRenderWindow->AddRenderer( mRenderer );
mRenderWindow->SetInteractor( mInteractor );
ui->openGLWidget->setRenderWindow(mRenderWindow);
mInteractor->SetInteractorStyle( mInteractorStyle );
mInteractor->Initialize();
mRenderer->SetBackground(0,0,1); // Set the initial render window to blue.
connect( ui->drawSphere_button, SIGNAL(clicked()), this, SLOT(onDrawSphereClick() ));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onDrawSphereClick()
{
vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetRadius( 5 );
sphereSource->SetPhiResolution(20);
sphereSource->SetThetaResolution(20);
sphereSource->SetCenter(mx, my, mz);
sphereSource->Update();
vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
sphereMapper->SetInputData( sphereSource->GetOutput() );
vtkSmartPointer<vtkActor> sphere = vtkSmartPointer<vtkActor>::New();
sphere->SetMapper( sphereMapper );
mRenderer->AddActor( sphere );
mRenderer->ResetCamera();
mRenderer->SetBackground(1.0 - mc, mc, 0);
mRenderer->Render();
ui->openGLWidget->update();
//With the following 4 lines uncommented, it works.
//int x = ui->openGLWidget->width();
//int y = ui->openGLWidget->height();
//ui->openGLWidget->resize(x, y + 1);
//ui->openGLWidget->resize(x, y);
// Update position ready for next sphere.
mx += 10;
if (mx > 20)
{
mx = -20;
my += 10;
if (my > 20)
{
my = -20;
mz += 10;
}
}
// Update colour ready for next background
mc += 0.1;
if (mc >= 1.0) mc = 0;
}
And the associated header file for MainWindow
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkRenderer.h>
#include <QVTKInteractor.h>
#include <vtkInteractorStyle.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow( QWidget *parent = nullptr );
~MainWindow();
public slots:
void onDrawSphereClick();
private:
Ui::MainWindow* ui;
vtkSmartPointer<vtkGenericOpenGLRenderWindow> mRenderWindow;
vtkSmartPointer<vtkRenderer> mRenderer;
vtkSmartPointer<QVTKInteractor> mInteractor;
vtkSmartPointer<vtkInteractorStyle> mInteractorStyle;
int mx = -20; // Position of next sphere in stack.
int my = -20;
int mz = -20;
double mc = 0; // Next background colour ( 0 = Red through to 1 = Green)
};
#endif // MAINWINDOW_H
I am getting the same problem (not redrawing until I resize) whether I use QVTKOpenGLNativeWindow, QVTKOpenGLWidget or QVTKOpenGLStereoWidget. Is there something I’m missing that is causing the image not to be redrawn simply with these after the new actor and colour change have been added to the scene?
mRenderer->Render();
ui->openGLWidget->update();