为什么在访问 vtkRenderWindow 的 ```Interactor``` 变量时会发生段错误?

Why does a segfault occur when accessing vtkRenderWindow's ```Interactor``` variable?

我有一个在 Ubuntu 20.04 LTS 上使用 VTK 9.0 和 QT 5.14.2 的应用程序。它编译得很好(使用 gcc)并且大部分应用程序都可以运行。但是,当我尝试创建 vtkRenderWindow 时,它因段错误而崩溃。具体来说,每当我的应用程序尝试访问 vtkRenderWindow 对象的受保护 Interactor 变量(在 vtkRenderWindow.h:754 中声明)或与之交互时。

vtkRenderWindowInteractor* Interactor;

到目前为止,我遇到过 (1) vtkRenderWindow::GetInteractor()(2) [=19] 崩溃=], 和 (3) vtkRenderWindow::MakeRenderWindowInteractor().

(1) 更准确地说,程序在尝试执行 vtkRenderWindow::GetInteractor() 的那一刻崩溃了。我调用 VTK 函数的代码:

vtkRenderer* m_Ren1;
vtkRenderWindow* renwin;
Ui::vtkwindow_new *ui;
QVTKOpenGLStereoWidget* qVTK1;

m_Ren1 = vtkRenderer::New();
renwin = vtkRenderWindow::New();
renwin->AddRenderer(m_Ren1);
ui->qVTK1->setRenderWindow(renwin);

ui->qVTK1->renderWindow()->GetInteractor();

(2) 调用 vtkRenderWindow::SetInteractor() 时,它在 vtkRenderWindow.cxx:155 处崩溃,在该行 if (this->Interactor != rwi)。我在下面显示我使用的代码:

vtkRenderer* m_Ren1;
vtkRenderWindow* renwin;
Ui::vtkwindow_new *ui;
QVTKOpenGLStereoWidget* qVTK1;

m_Ren1 = vtkRenderer::New();
renwin = vtkRenderWindow::New();
renwin->AddRenderer(m_Ren1);
ui->qVTK1->setRenderWindow(renwin);

vtkRenderWindowInteractor* t1 = vtkRenderWindowInteractor::New();
ui->qVTK1->renderWindow()->SetInteractor(t1);

(3)调用vtkRenderWindow::MakeRenderWindowInteractor()时崩溃在vtkObjectFactory.cxx:438,特别是在调用strcmp函数时。

if (this->OverrideArray[i].EnabledFlag &&
  strcmp(this->OverrideClassNames[i], vtkclassname) == 0)

再次,我在下面展示了我用来测试这个的代码:

vtkRenderer* m_Ren1;
vtkRenderWindow* renwin;
Ui::vtkwindow_new *ui;
QVTKOpenGLStereoWidget* qVTK1;

m_Ren1 = vtkRenderer::New();
renwin = vtkRenderWindow::New();
renwin->AddRenderer(m_Ren1);
ui->qVTK1->setRenderWindow(renwin);
ui->qVTK1->renderWindow()->MakeRenderWindowInteractor();

奇怪的是,尽管 testqVTK1->renderWindow() 都是 vtkXOpenGLRenderWindow 类型,但如果我如下创建新的 RenderWindow,程序不会崩溃。无论我将 qVTK1->renderWindow() 的交互器设置为 t1 还是 t2:

,它都会崩溃
vtkRenderWindow* test = vtkRenderWindow::New();
vtkRenderWindowInteractor* t2 = test->GetInteractor();
vtkRenderWindowInteractor* t1 = vtkRenderWindowInteractor::New();
test->SetInteractor(t1);
ui->qVTK1->renderWindow()->SetInteractor(t1);
ui->qVTK1->renderWindow()->SetInteractor(t2);

如果有人知道为什么会发生这种情况或如何处理,我将不胜感激。我也在 VTK 论坛上问过,但一周后还没有收到答复。我无法在任何地方找到描述的类似案例。鉴于所有崩溃都发生在 VTK 库代码中,我对导致崩溃的原因感到非常困惑。

谢谢!

已解决!问题其实是从QT这边来的。 QVTKOpenGLRenderWindow 无法处理 vtkXOpenGLRenderWindow,它需要 vtkGenericOpenGLRenderWindow。但是 vtkGenericOpenGLRenderWindow 不能用 vtkRenderWindow::New() 创建。解决方案是声明渲染窗口包裹在 vtkNew<> 指针中:

    vtkRenderer* m_Ren1;
    vtkRenderWindow* renwin;
    QVTKOpenGLStereoWidget* qVTK1;

    m_Ren1 = vtkRenderer::New();

    vtkNew<vtkGenericOpenGLRenderWindow> rw;
    renwin = rw;

    renwin->AddRenderer(m_Ren1);
    ui->qVTK1->setRenderWindow(renwin);

这解决了交互器的问题。