How to get the current ROINode programmingly according to the volume in the volume rendering module?

There are three volumes in the volume rendering module and there are three corresponding AnnotationROIs,as follows:

yeah,I want to get the current ROINode,for example right now,I choose the first volume so I get the vtkMRMLAnnotationROINode1 and when I change to select the second volume the ROINode should be vtkMRMLAnnotationROINode2.
Usually, I hard code to get the ROINode but it is not convenient:

# get the first ROINode
roi = slicer.mrmlScene.GetNodeByID(AnnotationROINodeID)

# get the second ROINode
roi = slicer.mrmlScene.GetNodeByID(AnnotationROINodeID)

So,is there a way to get the current roiNode according to the selected volume?
Thank you in advance for your possible advice!

This should work for that:

myVolumeName = 'MRHead' # replace with the displayed name of your volume
volNode = getNode(volumeName) # get the mrml scalar volume node
vrLogic = slicer.modules.volumerendering.logic() #  get the volume rendering module logic
vrDispNode = logic.GetFirstVolumeRenderingDisplayNode(volNode) # get the volume rendering display node 
roiNode = vrDispNode.GetROINode() # get the associated ROI node

If you have an ROI node and want to know which volume is rendered using that node, you can do this

vrLogic = slicer.modules.volumerendering.logic()
vrDispNode = logic.GetFirstVolumeRenderingDisplayNodeByROINode(roiNode)

See the documentation here: Slicer: vtkSlicerVolumeRenderingLogic Class Reference

Thanks Mike,
This is not working and also I have seen the documentation ,still can’t figure it out.
Maybe I am not making myself clear,my end goal is to take screenshots as png files as you helped me before.But when I load a scene.mrml file into Slicer ,there are three volumes.
I have currently designed a GUI like this:

I can take screenshots given the necessary parameters ,but only the first volume,which means if I select the second volume in volume rendering module and click the eye icon to see it in display area,I still take screenshots in the first volume.So what I what is as follows:
select the second volume and make it displayed:

Is there someway to get the ROINode at the moment I selected the volume or clicked the eye icon to see it?
In other words,at the moment I selected the third volume and clicked the eye icon,the ROINode should change itself.
Thank you for your continued attention on this topic!

I notice there was a typo in the included code from two posts ago. I had changed a variable called logic to vrLogic to try to be a little clearer, but I didn’t change it everywhere in the pasted code. Hopefully that’s all that was leading to your errors.

vrLogic = slicer.modules.volumerendering.logic()

vol1node = getNode('vol1')
vol2node = getNode('vol2')

# Get or create the volume rendering display node for vol1
vrDispNode1 = vrLogic.GetFirstVolumeRenderingDisplayNode(vol1node)
if vrDispNode1 is None:
  # no existing display node, create a new one
  vrDispNode1 = vrLogic.CreateDefaultVolumeRenderingNodes(vol1Node)

# Get or create the volume rendering display node for vol2
vrDispNode2 = vrLogic.GetFirstVolumeRenderingDisplayNode(vol2node)
if vrDispNode2 is None:
  vrDispNode2  = vrLogic.CreateDefaultVolumeRenderingNodes(vol2node)


# To show vol2 instead of vol1
vrDispNode1.SetVisibility(0) # hide vol1 rendering
vrDispNode2.SetVisibility(1) # show vol2 rendering
1 Like

Thanks Mike, it is not about the type error.It seems like if I want the ROINode I have to get the volumeNode by ID or name.
Thank you for your code and help anyway!

I think I’m not totally clear on what the problem you are running into is. I thought you were saying that the problem you were having was that the first volume rendering was being captured twice instead of switching to the second volume, so I was showing how to hide one volume rendering and show another.

Separately, once you have a volume rendering display node, you can get the ROI node from that via the GetROINode() method.