Thanks! that was definitely a step in the right direction, but things aren’t quite working the way I want them to.
Some context: I’m trying to write a module where a user can select a volume (using a standard qMRMLNodeComboBox), and then, among other things, that volume gets displayed in a 3D view (and also a slice view). I want the volume to switch if the user changes the selected volume.
My function (called, ultimately, from the selector’s currentNodeChanged(bool) signal) looks like this:
def showVolumeIn3DView(volumeNode):
renderingLogic = slicer.modules.volumerendering.logic()
displayNode = renderingLogic.CreateDefaultVolumeRenderingNodes(volumeNode)
widget = slicer.app.layoutManager().threeDWidget(0) # See note below
displayNode.SetViewNodeIDs([widget.mrmlViewNode().GetID()])
renderingLogic.UpdateDisplayNodeFromVolumeNode(displayNode, volumeNode)
Before I added the last line (which I found here), the volume that was active before opening my module was shown in the 3D view, and didn’t change at all. With this line, it does change – but only the first time every volume is selected. That is, if Vol1 was active, the module opens showing Vol1. Now,
- select Vol2 → shows Vol2.
- Then, select Vol1 again → still shows Vol2, nothing happens in the 3D view.
I’ve tried storing the displayNode, and calling renderingLogic.RemoveVolumeRenderingDisplayNode() on the “old” displayNode before the CreateDefaultVolumeRenderingNodes() for the new volume, thinking that would help reset the display node – but it did nothing. I also tried to do
displayNode.SetViewNodeIDs([])
displayNode.SetViewNodeIDs([widget.mrmlViewNode().GetID()])
to try to force the display node to “re-install” itself on the view node – again, to no avail. I also tried both together. I have to say, my instinct is still that I’m trying things in a fundamentally misguided way – except, I could find no guide…
While working on this, I think I also found a bug in the view node management. Docs seem to indicate I can pick a 3D-view by name; for slice views, this “name” is the value set in the layout XML by the singletontag attribute. But for 3D views – first, the name gets a funny prefix; but then, the function just doesn’t work at all, always returning None. The singleton tag I used for the 3D view was “1”.
>>> lm = slicer.app.layoutManager()
>>> w = lm.threeDWidget(0)
>>> w.name
'ThreeDWidget1'
>>> lm.threeDWidget('ThreeDWidget1')
>>> print(lm.threeDWidget(w.name))
None
Thanks again – you’ve already been very helpful!