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!