vtkWorldPointPicker seems not working for multi-layer rendering

Hello,

I am trying to use the vtkWorldPointPicker to obtain just the picked position under the mouse cursor.

auto picker = vtkSmartPointer<vtkWorldPointPicker>::New();
picker->Pick(clickPos[0], clickPos[1], 0, renderer);
auto position = picker->GetPickPosition();

In case that just single renderer is used the picker works as expected. But in case that two layered renderers are used:

auto renderer1 =
        vtkSmartPointer<vtkRenderer>::New();
renderer1->SetLayer(1);
renderWindow->SetNumberOfLayers(2);
renderWindow->AddRenderer(renderer1);

the picker does not pick the rendered pixel position anymore.

To demonstrate the problem I made a simple demo PickPosition.cxx. There are several spheres in the scene. Left mouse click invokes the vtkWorldPointPicker to get the position of pixel under the mouse cursor. Then a cross mark is placed at the picked position to visually verify it.

When lines 114-118 are commented out and there is just single renderer the picking works as expected - when mouse clicked over any sphere the cross mark is placed correctly at the sphere surface. But in case the second renderer is added (lines 114-118 are uncommented) picking always fails.

Am I using the picker correctly? Is it a bug?

Originally I used the vtkPropPicker, that uses the vtkWorldPointPicker internally to return the PickPosition(). I have found that the vtkPropPicker works fine even for more layered renderers in the 8.1.x versions but is not working for layered renderers in 8.2.0. Strange thing is that vtkWorldPointPicker does not work for layered renderers even in 8.1.x nor in 8.2.0.

To test the vtkPropPicker one can switch the the style type on the line 126.

Can someone help me please? How can I pick pixel position for multi layered renderers in the 8.2.0? Ideas, hints, explanations, … whatever.

Petr

Let me share what I have found so far:

The cause of the problem is the fact that in case that 2 layered vtkRenderers are used the call:

double z = renderer->GetZ(x,y);

returns always 1 regardless there is any prop at the given position in the Z-buffer or not (1 means there is no prop). Seems to me as a bug, or not?

vtkWorldPointPicker::Pick(x,y,z,renderer) uses this call in the implementation. vtkPropPicker::Pick(x,y,z,renderer) then uses the mentioned vtkWorldPointPicker::Pick internally so both pickers fail.

For those interested in a workaround:

Use directly the vtkRenderer::PickProp() and then extract the Z display coordinate by the vtkRenderer::GetZ()

if(renderer->PickProp(clickPos[0], clickPos[1]) == nullptr)
    return nullptr;

double display[3];
display[0] = clickPos[0];
display[1] = clickPos[1];
display[2] = renderer->GetPickedZ();

Finally convert the display coordinates to world:

renderer->SetDisplayPoint (display);
renderer->DisplayToWorld ();
double * world = renderer->GetWorldPoint ();

double * picked = new double[3];
for (int i=0; i < 3; i++) {
    picked[i] = world[i] / world[3];
}

But note that this works only with the current vtk master branch. To make it work with the 8.2.0 release one has to apply the !6009 merge request. For complete working solution see the updated PickPosition.cxx.

Please note that the source code line numbers mentioned in the initial post are valid just in this version of the PickPosition.cxx

See here:
vtkPropPicker in VTK 9.1 is now returning wrong world coordinates. - Development - VTK