Commit 21d89be1 authored by Thomas Dowrick's avatar Thomas Dowrick

Issue #90: Add MouseWheelSliceViewer for manual cotrol of slice location

parent 98c6440b
Pipeline #3922 passed with stages
in 6 minutes and 23 seconds
""" Example usage of using the vtk reslice widgets.
`python vtk_reslice.py` - loads Viewer with mouse wheel scrolling.
'python vtk_reslice.py tracked' - loads Viewer with ArUco tracker for
slice control.
"""
import sys
from PySide2 import QtWidgets
from sksurgeryvtk.widgets.vtk_reslice_widget import TrackedSliceViewer
from sksurgeryvtk.widgets.vtk_reslice_widget import TrackedSliceViewer, \
MouseWheelSliceViewer
from sksurgeryarucotracker.arucotracker import ArUcoTracker
qApp = QtWidgets.QApplication([])
dicom_path = 'tests/data/dicom/LegoPhantom_3slices'
tracker = ArUcoTracker({})
tracker.start_tracking()
n_args = len(sys.argv)
if n_args > 1 and sys.argv[1] == "tracked":
tracker = ArUcoTracker({})
tracker.start_tracking()
slice_viewer = TrackedSliceViewer(dicom_path, tracker)
else:
slice_viewer = MouseWheelSliceViewer(dicom_path)
slice_viewer = TrackedSliceViewer(dicom_path, tracker)
slice_viewer.start()
qApp.exec_()
......@@ -24,6 +24,7 @@ class VTKResliceWidget(QVTKRenderWindowInteractor):
super().__init__(parent)
self.axis = axis
self.position = 0
# Calculate the center of the volume
self.x_min, self.x_max, self.y_min, self.y_max, self.z_min, self.z_max \
......@@ -72,6 +73,10 @@ class VTKResliceWidget(QVTKRenderWindowInteractor):
self.renderer.ResetCamera(self.actor.GetBounds())
self.GetRenderWindow().AddRenderer(self.renderer)
# Remove zoom behaviour for mouse wheel
self._Iren.RemoveObservers('MouseWheelForwardEvent')
self._Iren.RemoveObservers('MouseWheelBackwardEvent')
def set_slice_position(self, pos):
""" Set the slice position in the volume """
......@@ -92,10 +97,37 @@ class VTKResliceWidget(QVTKRenderWindowInteractor):
self.actor.SetDisplayExtent(
self.x_min, self.x_max, self.y_min, self.y_max, pos, pos)
self.position = pos
# Fill widget with slice by moving camera
self.renderer.ResetCamera(self.actor.GetBounds())
self.GetRenderWindow().Render()
def get_slice_position(self):
""" Return the current slice position. """
return self.position
def on_mouse_wheel_forward(self, obj, event):
#pylint:disable=unused-argument
""" Callback to change slice position using mouse wheel. """
current_position = self.get_slice_position()
self.set_slice_position(current_position + 1)
def on_mouse_wheel_backward(self, obj, event):
#pylint:disable=unused-argument
""" Callback to change slice position using mouse wheel. """
current_position = self.get_slice_position()
self.set_slice_position(current_position - 1)
def set_mouse_wheel_callbacks(self):
""" Add callbacks for scroll events. """
self._Iren.AddObserver('MouseWheelForwardEvent',
self.on_mouse_wheel_forward)
self._Iren.AddObserver('MouseWheelBackwardEvent',
self.on_mouse_wheel_backward)
class VTKSliceViewer(QtWidgets.QWidget):
""" Othrogonal slice viewer showing Axial/Sagittal/Coronal views
:param dicom_dir: path to folder containig dicom data """
......@@ -157,6 +189,35 @@ class VTKSliceViewer(QtWidgets.QWidget):
self.update_slice_positions(0, 0, 0)
class MouseWheelSliceViewer(VTKSliceViewer):
""" Orthogonal slice viewer using mouse wheel to
control slice position. """
def __init__(self, dicom_dir):
super().__init__(dicom_dir)
self.x_view.set_mouse_wheel_callbacks()
self.y_view.set_mouse_wheel_callbacks()
self.z_view.set_mouse_wheel_callbacks()
self.update_rate = 20
def update_fourth_panel(self):
""" Update 3D view. """
self.fourth_panel.GetRenderWindow().Render()
def start(self):
#pylint:disable=attribute-defined-outside-init, no-member
""" Start a timer which will update the 3D view. """
self.timer = QTimer()
self.timer.timeout.connect(self.update_fourth_panel)
self.timer.start(1000.0 / self.update_rate)
self.show()
self.reset_slice_positions()
class TrackedSliceViewer(VTKSliceViewer):
#pylint:disable=invalid-name
......
......@@ -10,3 +10,12 @@ def test_slice_viewer(qtbot):
reslice.update_slice_positions(1,1,1)
def test_mouse_scroll_slice_viewer(qtbot):
dicom_path = 'tests/data/dicom/LegoPhantom_3slices'
reslice = vtk_reslice_widget.MouseWheelSliceViewer(dicom_path)
qtbot.addWidget(reslice)
reslice.update_slice_positions(1,1,1)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment