How to show a transform in only one view

I have a Displacement field Transform and I want to visualise it only in one 2D view. I couldn’t find it in the UI and I couldn’t figure out how to do it in python.

Is there a way to do that?

:robot: This post contains AI-generated content.

In the Transforms module, first turn on “Visible in 2D view” (under DisplayVisualization) so a transform display node exists and slice visualization is enabled. Then in the Python console:

transformNode = getNode("YourTransform")             # or pick by ID
displayNode = transformNode.GetDisplayNode()         # created when 2D vis is toggled on

# Restrict to a single slice view (e.g., Red):
displayNode.SetViewNodeIDs(["vtkMRMLSliceNodeRed"])

To go back to “all views”, clear the list:

displayNode.RemoveAllViewNodeIDs()

Notes:

  • The IDs for the default slice views are vtkMRMLSliceNodeRed, vtkMRMLSliceNodeYellow, vtkMRMLSliceNodeGreen. For a custom view, grab sliceNode.GetID().
  • If GetDisplayNode() returns None, call transformNode.CreateDefaultDisplayNodes() first, or just toggle the 2D-visible checkbox once in the Transforms module.
  • This restriction also applies to the visualization region/ROI — only the listed view will render the grid/glyph/contour.

This doesn’t work for me. In which Slicer version has this worked for you? I’m in the stable release 5.10.0

  1. there is no “Visible in 2D view”, I only see “Visibility:”, “Visibility in slice view:” and “Visibility in 3D view:” - I have all of them checked
  2. no matter what ViewNodeIDs I set, it always remains visible in all views

:robot: This post was written with AI assistance.

I am also in 5.10 but had not tried the snippet.

(“Visibility in slice view” is the correct label, thanks)

When I tried it, indeed the grid/glyph/contour remains visible in all slice views.

It took some trickery, here is the ai generated snippet that finally worked:

transformNode = getNode("YourTransform")
old = transformNode.GetDisplayNode()
if old:
    slicer.mrmlScene.RemoveNode(old)

# Create and configure the display node BEFORE attaching it to the transform.
# Until it's linked, no displayable manager will process it, so we can set
# the view filter and visibility flags safely.
dn = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLTransformDisplayNode")
dn.SetViewNodeIDs(["vtkMRMLSliceNodeRed"])
dn.SetVisibility(True)
dn.SetVisibility2D(True)
dn.SetVisibility3D(False)

# Link last — this is the moment UseDisplayNode() runs in each slice manager,
# and only the Red one will pass the IsDisplayableInView() check.
transformNode.SetAndObserveDisplayNodeID(dn.GetID())

The problem was that the transform 2D displayable manager is not noticing changes to the view filter. We could add to vtkMRMLTransformsDisplayableManager2D.cxx#L149 a && displayNode->IsDisplayableInView(this->SliceNode->GetID())

Often, you can get an update to be noticed in Slicer by calling node.Modified(). You could try that on the transform node (or maybe the display node).