Speedup initial display

Hi friends,

I’m using VTK to display a huge number of (simple) objects.
Each object has its own color & visibility & pickability.

I’m trying to achieve the best performances possible.
I’ve chosen to use a CompositePolyDataMapper2, linked to a MultiBlockDataSet to store objects.
Each object is composed of a MultiBlockDataSet with 2 sub-blocks : one for triangulated faces, one for edges.

The main bottleneck is the first scene display, when I call vtkRenderWindow.Render() for the first time after scene creation.

Typically, on a scene with 2000 objects / 100000 triangles / 10000 edges, initial render takes up to 20-25s (Ryzen 5700G + 32Go).
After initial display, scene is smooth (pan / rotate / zoom).

Another thing that is slow is object update.
When user select an object in the scene, I change its color.
For that I use CompositePolyDataMapper2.SetBlockColor(…) + vtkRenderWindow.Render() to update scene.
It works, but I see some lag (maybe 700-1000ms) after a selection/deselection.

Do you think speed issue is due to MultiBlockDataSet ?
Do you have any advice to make things faster ?

Thanks a lot !

Yes

Put all in a single object.

Yes, but as far as I can understand, I will loose individual picking / color ?

Will passing to the “vtkPartitionedDataSet” paradigm could improve perfs ?

I’ve tested putting all geometries inside a unique PolyData.
Performance improvement is just insane (all is almost instant).
Will try to deal with “cells” to obtain per object color / picking.

Thanks Mathieu.

1 Like

Yes, CellData is the way for color and picking.

Please Mathieu, could you confirm the following points :

  • I cannot display opaque and transparent cell inside a unique PolyData at the same time ?
  • If I want to hide some cells inside a PolyData, I have to filter them with, for example, a vtkSelection ?

Thank you in advance.

I cannot display opaque and transparent cell inside a unique PolyData at the same time ?

Not with the standard vtkPolyDataMapper, but creating a dedicated mapper for that should not be that hard

If I want to hide some cells inside a PolyData, I have to filter them with, for example, a vtkSelection ?

The better way is the mapper way, but can be done less efficiently with a selection, yes.

Mathieu,

I’m back after some testing with vtkSelection + vtkExtractSelectedPolyDataIds / vtkExtractSelection.
I’m having some issues I don’t want to deal with for now.

So, please could you elaborate a little more on “the Mapper way” ?

I guess I’ll have to inherit my own Mapper from vtk’s one, but don’t know exactly where to start from.
If it inherits from vtkPolydatMapper, obviously vtkOpenGLPolyDataMapper will not make use of it when instantiated.
I could thus inherits directly from vtkOpenGLPolyDataMapper, bypassing VTK natural behavior when creating a mapper with generic function ?

Additionally, to achieve “mixed opacity” and “cell visibility” features, what could be the best approach within this overridden Mapper ?
Are there specific methods I’ll have to modify ?

I will take a deep look into VTK code to try to answer all this by myself of course.
I’m just asking for general hints.
Thank in advance.

Hello, good day,
pmfji, I just want to inform that I am very interested about the questions and answers in this thread too since I am dealing with a similar challenge as Oliver with the difference that I have to deal with a number of 120000+ graphical objects individually pickable, colored and filtered.
Therefore I am very interested how to derive an own mapper. A hint or pointing to an example (if exists) would be great too.

Many thanks in advance,
Jens

Hi Jens,

I have not yet taken a look to source code, because it is not that easy to understand the whole logic, and to avoid doing bad things.

But, until now here what I’ve done and seen :

  • Using more than several 10th of actors leads it huge performance hit.
  • Using more than several 10th of PolyData inside a MultiBlockDataSet leads to huge performance hit.
  • Putting all geometries inside a unique PolyData give best display performances, but loose all the easy logic to Pick / Color / Hide single objects.

So if you want to display huge number a objects with VTK, by using existing mechanisms, the only solution I’ve found so far is to :

  • Put all geometry inside a unique PolyData → Mapper → Actor.

  • Feeding points/triangles by appending all geometries.

  • Using Cell data to identify each cell’s parent solid for picking, thanks to data.GetCellData().SetGlobalIds(...)
    Then you can pick like that

vtkNew<vtkCellPicker> picker;
picker->Pick(clickPos[0], clickPos[1], 0, GetCurrentRenderer());
auto globalids = reinterpret_cast<vtkIdTypeArray*>(picker->GetDataSet()->GetCellData()->GetGlobalIds());
auto gid = globalids->GetValue(picker->GetCellId());
  • Using data.GetCellData().SetScalars to set colors of each cell according to parent’s one.
    Beware that mixing opaque & translucent geometries inside a unique Mapper is not allowed, you will have to split all your objects into two batches.

The major drawback is that, for each change in your objects (visibility, colors, …) you will have more or less to regen the whole thing, this can lead to performance hit.
To minimize that, you may find a good balance between PolyData’s size and number.

Hi Oliver,
many thanks for your hint and instruction.
I am still in an investigation phase if vtk is the right choice for my requirements and planned projects. At the beginning I am a real novice in 3D prgramming but since oberserving here, reading books and playing with vtk and testing I am not sure yet about VTK. I have no clue if there are similar (but easier and faster to use) 3D open source class libraries available.
I will try your sample code which is much appreciated.
Many thanks for it and have a nice day,
Jens

VTK is the right choice if you need its “enhanced display” capacities.
For example if you need to display “volumes” / “contours”, etc …

If you only need it to display very basic geometry with many object, it may not be the best option.
In the free world, you’ll have many OpenGL frontend available, with several level of features.
You have for example OpenCascade Viewer that provide many high level features (SSAO, RayTracing, Textures, …) with top performances.
You have many direct OpenGL wrappers around here that could do the trick for you.
Qt provides a good 3D wrapper too.
etc etc …

On the paid side, you have several solutions.
I’ve tested Devdept Eyeshot that is pretty good (but C#).
You may test either games engines (Godot, Unreal, Unity, Stride, WaveEngine, etc …).