vtkPropPicker in VTK 9.1 is now returning wrong world coordinates.

Hi Paulo, I meet the same problem as you reported!

In my situation, I added an extra renderer to the render window to do overlay drawing for annotation stuffs. After that, “vtkRenderer::GetZ” almost returns value 1.0 at every time. Then I digged into the issue by exporting z buffer as an image file, guess what? It’s the depth buffer of the annotation render layer! I found that multiple renderers are invoked one by one in the RendererCollections, so the second annotation renderer clear the depth buffer immediately which made vtkWorldPointPicker to catch the second layer depth buffer.

The way I handle this problem is by observing the vtkCommand::EndEvent to the main renderer, and invoke vtkWorldPointPicker in the callback when it is needed with the current mouse position as input, then cache the correct result. After this, an extra rendering invocation is need before fetching the cache.

By the way, I don’t think it’s an issue caused by VTK9.1 upgrade since I was using the older VTK8.2.0.

Hopes to help every one whom has being struggling in the same issue!

It is up to you to decide if you want your annotation layer to clear the Z buffer or not (see vtkRenderer::SetPreserveDepthBuffer).
Grabbing the depth buffer after rendering certain layers may be a good solution, too.

Hello,

That never occured to me. Funny, I too use two renderers in my project. Maybe I should try @lassoan 's suggestion and review the solution as well as the fixing commit in VTK code. Thanks for the heads up.

best,

PC

I just need some time to setup my development environment since my previous computer failed.

Lassoan’s idea sounds better, which avoids an extra rendering invocation. And eliminates mouse position prediction, that means every screen position can be computed to output a world position based on depth buffer. Then, how to cache the depth buffer in an efficient way should be considered.
Thanks!

Depending on what you need, you may find vtkSelectVisiblePoints useful for getting and caching the Z buffer.

Unfortunately VTK 9.3 is not compilable in debug mode with MinGW64 (the compiler I use in Windows). I have somehow to recover my patched version of VTK 9.1 (to allow compiling with MinGW64).

VTK 9.1 is also not compilable (at least without extensive patching) in debug mode with the version 13.2.0 of MinGW64’s gcc…

Your solution solves the Z issue, but makes the foreground renderer pointless to display always-on-top labels:

In the example above, I did a SetPreserveDepthBuffer( true ) on the foreground renderer, now the labels are occluded by the geomertry.

I’ll experiment a bit with it in the mouse events to try to get it right.

thanks,

PC

So, inspired by your solution, I came up with a little dirty trick in my mouse-up event:

        m_ParentView3DWidget->getForegroundRenderer()->SetPreserveDepthBuffer( true );
        m_ParentView3DWidget->getRenderer()->Render();

        [PICKING CODE]

        m_ParentView3DWidget->getForegroundRenderer()->SetPreserveDepthBuffer( false );
        m_ParentView3DWidget->getRenderer()->Render();

So, I believe the change to the GetZ method proposed by me can be reverted to restore it’s previous performance.

1 Like

The second Render() call is not actually necessary in my case.

Seems like the label actor is too close to the background model, the label quad primitives are not able to pass the z-test progress of the rendering pipeline.

In my case, “SetPreserveDepthBuffer” is not needed since I catch the z-buffer immediately just before it being cleared by the foreground renderer by hooking the “EndEvent”. It needs to know which screen position is working on, so I invoked an extra rendering and with current mouse position to pick the world position.
For the performance consideration, I believe this extra rendering can be avoided by catching the entire z-buffer, then every screen position is able to be picked, but it should be done along with every rendering invocation since it didn’t know when you need it. Compared to a single extra rendering, it doesn’t seem like a better choice.