vtkmodules.qt.QVTKRenderWindowInteractor problems

Hello,

I have problems using the QVTKRenderWindowInteractor within Python.

At first the setup:
OS: Windows10
Python: 3.7.9
PyQt: 5.15.1
VTK: 9.0.1 (I built it with ‘python -m pip install vtk’)

I had problems with the QVTKRenderWindowInteractor from package ‘from vtkmodules.qt.QVTKRenderWindowInteractor’.
I got the error message:
‘vtkInteractorStyleSwitc:37 WARN| vtkInteractorStyleSwitchBase (00000233904378E0): Warning: Link to vtkInteractionStyle for default style selection.’

After reviewing the QVTKRenderWidgetConeExample I saw that
‘import vtkmodules.vtkRenderingOpenGL2
import vtkmodules.vtkInteractionStyle’
prevents this error message. (Why?)

As next step i wanted to add an vtkmodules.vtkRenderingCore.vtkTextActor:
textActor = vtkTextActor()
textActor.SetInput(“Test”)
ren.AddActor(textActor)
But now I got the next error message:
‘vtkTextActor.cxx:117 ERR| vtkTextActor (0000015B0D3347D0): Failed getting the TextRenderer instance!’
How can I solve this kind of errors?

Btw. when using ‘vtk.qt.QVTKRenderWindowInteractor.QVTKRenderWindowInteractor’ instead of ‘vtkmodules.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor’ everything works fine.

What is the proper way to work with vtk in Python? (I’m just beginning to use it)
In the Eclipse IDE I get import suggestions of vtkmodules instead of vtk, why I thought vtkmodules is the correct one.

Many thanks in advance for your help!
-crux

VTK has some classes which are abstract factories. When loaded, some libraries (accessed in Python by importing them) register implementations of these abstract factories for use when asking for an instance of the base abstract factory. Without any registered classes, you get the first error you encountered. The vtkInteractionStyle module happens to include one of these implementations for vtkInteractorStyleSwitchBase which is why it fixes the problem.

You have a similar issue with vtkTextRenderer in the second message. vtkRenderingFreeType contains an implementation of that class, so importing it would fix that error.

Using vtk.qt.… works because the vtk module imports all of vtkmodules when it is loaded. Due to this behavior, to get on-demand loading, the vtkmodules package was created instead.

Thank you for the fast response.

Okay this approach makes sense. But how do i know which libraries I have to import to register the abstract factories? For example for vtkTextRenderer?

Unfortunately, there’s no way for the base class to know what you actually want. What I did was grep for vtkTextRenderer in the CMakeLists.txt files in VTK’s repo and saw that there was a BASE vtkTextRenderer in the Rendering/FreeType directory. Since it was the only one provided by VTK itself, this seems like the best solution.

Okay cool, thank you very much for the advice and the solution!

When i change import vtkmodules.vtkInteractionStyle to import vtkmodules.vtkInteractionWidgets it also works :-).

VTK itself provides exactly one implementation class for each abstract factory class, so a simple work-around is to load all of the VTK modules.

This can be done by using

import vtk

instead of

import vtkmodules.xxx

Using the “vtkmodules” package to import only the modules you need is more efficient than using the “vtk” package to load all modules, but this must be weighed against the ease-of-use of “import vtk”.

The situation could be improved greatly through better error messages, but unfortunately VTK itself does not provide any mapping that states, for any particular abstract factory class, what modules the implementation classes are stored in.

There are some classes with multiple implementations possible. vtkOpenGLRenderWindow has X (potentially) available on any platform. There are also OpenVR implementations for lots of things.

I’m not familiar with the situation with OpenVR, but my understanding was that the implementations for vtkRenderWindow were mutually exclusive. This is implied by the structure of the CMakeLists.txt:

if (VTK_USE_X)
elseif (WIN32)
elseif (VTK_USE_COCOA)
elseif (ANDROID)
elseif (APPLE_IOS)
endif ()

Am I missing something?

Oh, maybe they are, but there’s no reason they should be. There’s a problem in that whatever gets registered first “wins” when there are multiples available. There’s an issue for that though.

So I guess that we can agree that the vtkRenderWindow overrides that exist in vtkRenderingOpenGL2 must either be 1) mutually exclusive, since they are all implemented in the same module, or 2) selectable as per the issue that you linked. Since the issue you linked is not yet resolved, it seems that mutual exclusivity is, in fact, required.