Get volume being shown in qMRMLThreeDView or vtkMRMLViewNode from Python

Supose I see a volume in a 3D view. Once I have that view instance in hands, how can I know which volume is being shown there? (instance = qMRMLThreeDView or vtkMRMLViewNode)

Thank you very much!

I think you could use a function to send a ray in the camera direction and see with what volume it collides first.
I think it could be possible but I don’t know how

1 Like

Thanks, Mauro. I believe your solution would give me some results, though I think it would not meet my needs well. I will try to make myself more clear:

If there is one or more volumes visible in the view, even if my camera is not pointing to them, I would like be able to list their IDs.

Ok. Then you just need to traverse all displayNodes of those volumes and

volumeDisplayNode = volumeNode.GetDisplayNode()
viewNodesIDs = volumeDisplayNode.GetViewNodeIDs()
visibility = False
for i in range(len(viewNodesIDs))
  visibility = volumeDisplayNode.GetVisibility() and volumeDisplayNode.GetViewNodeIDs()[i] == 'myParticularViewID'
  if visibility:
    break

if visibility:
  myListOfVisibleVolumesIDs.append(volumeNode.GetID())

to get ‘myParticularViewID’ just use GetID() on the viewNodeThatYouHave.

I think that should work.

1 Like

I think you walk in a good way. The issue is that volumeDisplayNode.GetViewNodeIDs() gives me an empty tuple (()) (though in Slicer I definitely see the Red slice view showing my node). I saw in the documentation that it means “every view”. So I would advise people to list all 3D and slice views if they want to have control over the volume views of interest.

Also, thank you very much, @mau_igna_06 !

(almost three years later)

I was looking for this, and the answer given was insufficient for me (because GetViewNodeIDs() returns an empty tuple both for volumes displayed in all views, and for volumes displayed in no view).

I found a way to get from a sliceWidget to the displayed view – there is actually, potentially, more than one, because slice widgets can blend two volumes (background and foreground) and a label-map.

Anyway,

node = sliceWidget.sliceLogic().GetBackgroundLayer().GetVolumeNode()