Reproducible Slicer crash on use of slicer.vtkSlicerReformatLogic.SetSliceOrigin()

I am trying to get the hang of positioning a slice view within an image volume (as you can do interactively with the Reformat widget or module). Changing the slice normal seems to work fine and as I expect, but it Slicer has crashed every time I try to use the analogous function to set the slice origin. Here is code which reproducibly crashes slicer 4.10.1:

# Load sample image volume
import SampleData
sampleDataLogic = SampleData.SampleDataLogic()
sampleDataLogic.downloadMRHead()
# Get a slice node and the logic which does slice reformatting
redNode = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeRed')
reformatLogic = slicer.vtkSlicerReformatLogic()
# Pick a new slice normal
newNormal = [0,1,0]
# Apply that normal
reformatLogic.SetSliceNormal(redNode, newNormal) # this works fine
# Pick a new RAS origin
newOrigin = [0.0, 0.0, 0.0]
# Apply the origin change
reformatLogic.SetSliceOrigin(redNode, newOrigin) # this one crashes Slicer

And Slicer crashes. I am using 4.10.1 on Windows 10. I am happy to provide more info if you can tell me what you would want to know. Maybe the new origin is supposed to be supplied in some other form? It looks to me like the underlying C++ function is expecting either 3 separate coordinates or a single list of 3 coordinates, just like SetSliceNormal().

Any suggestions?

Thanks!

Instead of instantiating your own reformat logic, use the one provided by the instantiated Reformat module.

Here is how you could update the code. It also include some indentation fixes and an simpler way of using SampleDataLogic

# Load sample image volume
from SampleData import SampleDataLogic
SampleDataLogic().downloadMRHead()

# Get a slice node and the logic which does slice reformatting
redNode = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeRed')
reformatLogic = slicer.modules.reformat.logic()

# Pick a new slice normal
newNormal = [0, 1, 0]
# Apply that normal
reformatLogic.SetSliceNormal(redNode, newNormal)

# Pick a new RAS origin
newOrigin = [0.0, 0.0, 0.0]

# Apply the origin change
reformatLogic.SetSliceOrigin(redNode, newOrigin)
2 Likes

Thanks, this fixes the problem! I was lulled into a false sense of security by the SetSliceNormal working fine the way I was doing it.

After integrating this PR, the crash will also be fixed and the code you initially will be working.

Since the provided slice node is already associating with a scene, there was no need to explicitly require the logic to be associated with a scene.

It will even allow to simplify your example further:

from SampleData import SampleDataLogic
from slicer import vtkSlicerReformatLogic

# Load sample image volume
SampleDataLogic().downloadMRHead()

# Get a slice node and the logic which does slice reformatting
redNode = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeRed')

# Pick a new slice normal
newNormal = [0, 1, 0]

# Apply that normal
vtkSlicerReformatLogic.SetSliceNormal(redNode, newNormal)

# Pick a new RAS origin
newOrigin = [0.0, 0.0, 0.0]

# Apply the origin change
vtkSlicerReformatLogic.SetSliceOrigin(redNode, newOrigin)