Hide a volume programmatically

I am writing a custom module in Python and I would like to:

  1. Replace the active volume in the slice viewer (similar to clicking on the “eye” icon of a different volume) with the next volume in the subject hierarchy
  2. Shut the eye icon on the subject hierarchy of the volume I just turned off

I was able to do the first bit with the following chunk of code, but I can’t seem to shut the eye in the subject hierarchy–both eyes stay on even though only one volume is present in the slice viewer. Is it possible to shut that eye icon programmatically? Thank you very much!

#  self.shNode is a subjectHierarchy node
def viewNextVolume(self, reverse = False):
  # First, get all valid volume vtkIDs
  sceneID = self.shNode.GetSceneItemID()
  allChildren = []
  self.shNode.GetItemChildren(sceneID, allChildren)
  validChildren = [child for child in allChildren if self.shNode.GetItemDataNode(child).IsTypeOf("vtkMRMLScalarVolumeNode")]

  # Second, get the vtkID of the current volume
  layoutManager = slicer.app.layoutManager()
  redVolumeID=layoutManager.sliceWidget("Red").sliceLogic().GetSliceCompositeNode().GetBackgroundVolumeID()
  currentvtkID = self.shNode.GetItemByDataNode(slicer.mrmlScene.GetNodeByID(redVolumeID))

  # third, advance the slice viewer
  nextDex = (validChildren.index(currentvtkID) + 1* (-1)**reverse) % len(validChildren) 
  newNode = self.shNode.GetItemDataNode(validChildren[nextDex])
  for sliceViewName in layoutManager.sliceViewNames():
    compositeNode = layoutManager.sliceWidget(sliceViewName).sliceLogic().GetSliceCompositeNode()
    compositeNode.SetBackgroundVolumeID(newNode.GetID())
    layoutManager.sliceWidget(sliceViewName).fitSliceToBackground()

  # HOW TO SHUT OFF EYE OF PREVIOUS VOLUME?

For the MRHead example I can set the visibility in the subject hierarchy programmatically using:

volNode = getNode("MRHead")
shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(slicer.mrmlScene)
volItem = shNode.GetItemByDataNode(volNode)
pluginHandler = slicer.qSlicerSubjectHierarchyPluginHandler().instance()
volPlugin = pluginHandler.getOwnerPluginForSubjectHierarchyItem(volItem)
volPlugin.setDisplayVisibility(volItem, 0)
1 Like

I’m not sure why

volNode.GetDisplayNode().SetVisibility(0)
volNode.SetDisplayVisibility(0)

don’t work to hide the slice view of the volume, maybe someone else can weigh in? I also noticed if the volume is in a folder, hiding the folder does not hide the slice view of the volume.

See the following and the insights liked from there:
(ultimately it is due to turning the visibility on would only work for 2 volumes, since Slicer can’t show more than 2 volumes in a given slice view)

2 Likes

You can show-hide volumes in slice views by using slicer.util.setSliceViewerLayers().

You can hide volume rendering in 3D views like this (if you don’t want to use the subject hierarchy plugin based solution above):

vrDisplayNode = slicer.modules.volumerendering.logic().GetFirstVolumeRenderingDisplayNode(volumeNode)
# hide volume rendering:
vrDisplayNode.SetVisibility(False)
# prevent showing volume rendering if eye icon is clicked in Subject Hierarchy:
vrDisplayNode.SetShowMode(slicer.vtkMRMLDisplayNode.ShowIgnore)
2 Likes

slicer.util.setSliceViewerLayers() link worked very nicely for this purpose. Thanks!