vtkCellPicker ignores block visibility in vtkMultiBlockDataSet

Hi everyone !

When hiding a block of a vtkMultiBlockDataSet using vtkCompositeDataDisplayAttributes.SetBlockVisibility(block, False), vtkCellPicker still picks the hidden block when a pick operation is performed.

It seems the picker intersects the raw input dataset directly without checking block visibility set on the composite mapper. Is this behavior expected, and is there a built-in way to avoid picking hidden blocks?

Reproduction Code :

import vtkmodules.vtkInteractionStyle
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonDataModel import vtkMultiBlockDataSet
from vtkmodules.vtkFiltersSources import vtkSphereSource
from vtkmodules.vtkRenderingOpenGL2 import vtkCompositePolyDataMapper2
from vtkmodules.vtkRenderingCore import (
    vtkActor,
    vtkCompositeDataDisplayAttributes,
    vtkRenderWindow,
    vtkRenderWindowInteractor,
    vtkRenderer,
    vtkCellPicker
)

def main():
    # 1. Create a MultiBlockDataSet with two concentric spheres
    root = vtkMultiBlockDataSet()

    # Inner sphere
    sphere1 = vtkSphereSource()
    sphere1.SetCenter(0, 0, 0)
    sphere1.SetRadius(1.0)
    sphere1.Update()
    root.SetBlock(0, sphere1.GetOutput())

    # Outer sphere 2
    sphere2 = vtkSphereSource()
    sphere2.SetCenter(0, 0, 0)
    sphere2.SetRadius(2.0)
    sphere2.Update()
    root.SetBlock(1, sphere2.GetOutput())

    # Setup rendering using the composite mapper
    renderer = vtkRenderer()
    renderWindow = vtkRenderWindow()
    renderWindow.AddRenderer(renderer)
    
    renderWindowInteractor = vtkRenderWindowInteractor()
    renderWindowInteractor.SetRenderWindow(renderWindow)

    mapper = vtkCompositePolyDataMapper2()
    mapper.SetInputDataObject(root)

    # Hide the outer sphere (block 1) using display attributes
    attributes = vtkCompositeDataDisplayAttributes()
    mapper.SetCompositeDataDisplayAttributes(attributes)
    attributes.SetBlockVisibility(root.GetBlock(1), False)

    actor = vtkActor()
    actor.SetMapper(mapper)
    renderer.AddActor(actor)
    renderer.ResetCamera()
    renderWindow.Render()

    # Pick at the center of the window
    picker = vtkCellPicker()
    size = renderWindow.GetSize()
    picker.Pick(size[0] / 2, size[1] / 2, 0, renderer)
    
    print("Flat block index picked:", picker.GetFlatBlockIndex())
    # Expected: 1 (the visible inner sphere)
    # Actual: 2 (the hidden outer sphere)

    renderWindowInteractor.Start()

if __name__ == '__main__':
    main()

1 Like