Hi,
is there a quick way to synchronize the zoom factor across slice viewers?
Thanks
Stephan
Yes. Long-click on slice view link icon and enable hot-linking. Maybe it only synchronizes views that have the same orientation. If this is the case then you may need to write a few-line Python script that observes zoom factor changes in slice views and adjusts zoom factor in all the others.
Hi Andras,
Yes, that is correct.
Unfortunately, this is literally the first time ever I opened the Python interactor. But at least, some googling brought me this far, and it does what I want it to
redSlice = slicer.app.layoutManager().sliceWidget('Red').mrmlSliceNode()
yellowSlice = slicer.app.layoutManager().sliceWidget('Yellow').mrmlSliceNode()
redFOV = redSlice.GetFieldOfView()
yellowSlice.SetFieldOfView(redFOV[0], redFOV[1], redFOV[2])
However, it would be nice to not always have to call the zoom alignment manually. Is there some zoom change event to hook an observer to (in vtkCommand I could not find something that looked very promising, but maybe I just missed it)?
Thank you
Stephan
Nice work! I’ve extended your example with slice node observers, which update field of view in all other slice nodes automatically when a slice node is changed: see complete script here.
Great, thank you @lassoan . That’s exactly what I was looking for.
I just added a tiny bit of additional functionality, namely to toggle zoomSync on and off.
slicer.updatingSliceNodes = False
slicer.zoomSync = False
slicer.sliceNodes = [slicer.app.layoutManager().sliceWidget(viewName).mrmlSliceNode()
for viewName in slicer.app.layoutManager().sliceViewNames()]
def sliceModified(caller, event):
if slicer.updatingSliceNodes:
# prevent infinite loop of slice node updates triggering slice node updates
return
slicer.updatingSliceNodes = True
fov = caller.GetFieldOfView()
for sliceNode in slicer.sliceNodes:
if sliceNode != caller:
sliceNode.SetFieldOfView(*fov)
slicer.updatingSliceNodes = False
def toggleZoomSync():
if slicer.zoomSync:
# zoom sync is on already, therefore observer function is alread hooked, should be unhooked
for sliceNode in slicer.sliceNodes:
sliceNode.RemoveObserver(sliceNode.zoomChangeObserverTag)
slicer.zoomSync = False
else:
# zoom sync is off --> toogle to on (register observer function)
for sliceNode in slicer.sliceNodes:
sliceNode.zoomChangeObserverTag = sliceNode.AddObserver(vtk.vtkCommand.ModifiedEvent, sliceModified)
slicer.zoomSync = True
toggleZoomSync()
After running this code snippet once, calls to
toggleZoomSync()
toggle slice zoom synchronization on/off.