diff --git a/pyproject.toml b/pyproject.toml index 6dba1e7..fcc8093 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "trame-server >= 3.6", "trame-vuetify", "trame-vtk", - "trame-rca >= 2.0.1", + "trame-rca >= 2.2.0", "itk", "lxml", "pydicom", diff --git a/trame_slicer/rca_view/rca_view_factory.py b/trame_slicer/rca_view/rca_view_factory.py index fb6d41c..86e3d24 100644 --- a/trame_slicer/rca_view/rca_view_factory.py +++ b/trame_slicer/rca_view/rca_view_factory.py @@ -7,10 +7,11 @@ from slicer import vtkMRMLApplicationLogic, vtkMRMLScene from trame_client.widgets.html import Div -from trame_rca.utils import RcaEncoder, RcaRenderScheduler, RcaViewAdapter +from trame_rca.utils import RcaEncoder, RcaRenderScheduler, RcaViewAdapter, VtkWindow from trame_rca.widgets.rca import RemoteControlledArea from trame_server import Server from trame_server.utils.asynchronous import create_task +from vtkmodules.vtkCommonCore import vtkCommand from trame_slicer.core import ViewManager from trame_slicer.views import ( @@ -44,6 +45,7 @@ def register_rca_factories( target_fps: float = 30.0, blur_fps: float = 10.0, interactive_quality: int = 50, + rca_event_throttle_s: float | None = None, ) -> None: """ Helper function to register all RCA factories to a view manager. @@ -63,6 +65,7 @@ def register_rca_factories( blur_fps=blur_fps, interactive_quality=interactive_quality, populate_view_ui_f=populate_view_ui_f, + rca_event_throttle_s=rca_event_throttle_s, ) ) @@ -77,6 +80,16 @@ def schedule_render(self): self._scheduler.schedule_render() +class RcaWindow(VtkWindow): + """ + RCA Window wrapper fixing resize event for 2D views. + """ + + def process_resize_event(self, width, height): + super().process_resize_event(width, height) + self._iren.InvokeEvent(vtkCommand.WindowResizeEvent) + + class RemoteViewFactory(IViewFactory): def __init__( self, @@ -89,6 +102,7 @@ def __init__( blur_fps: float | None = None, interactive_quality: int | None = None, rca_encoder: RcaEncoder | str | None = None, + rca_event_throttle_s: float | None = None, ): """ :param server: Trame server. @@ -99,6 +113,7 @@ def __init__( :param blur_fps: Out of focus rendering speed. :param interactive_quality: Interactive RCA image encoding quality. :param rca_encoder: Encoder type to use for RCA image encoding. + :param rca_event_throttle_s: Number of wait seconds in between two process events. (default = 50ms / 20FPS) """ super().__init__() self._server = server @@ -110,6 +125,7 @@ def __init__( self._interactive_quality = interactive_quality self._rca_encoder = rca_encoder self._populate_view_ui_f = populate_view_ui_f + self._rca_event_throttle_s = rca_event_throttle_s if rca_event_throttle_s is not None else 0.05 def _get_slicer_view(self, view: RcaView) -> AbstractView: return view.slicer_view @@ -132,8 +148,9 @@ def _create_view( slicer_view.set_view_properties(view.properties) + rca_window = RcaWindow(slicer_view.render_window()) rca_scheduler = RcaRenderScheduler( - window=slicer_view.render_window(), + window=rca_window, interactive_quality=self._interactive_quality, rca_encoder=self._rca_encoder, target_fps=self._target_fps, @@ -143,7 +160,7 @@ def _create_view( self._create_vuetify_ui(view_id, slicer_view, rca_scheduler) rca_view_adapter = RcaViewAdapter( - window=slicer_view.render_window(), + window=rca_window, name=view_id, scheduler=rca_scheduler, do_schedule_render_on_interaction=False, @@ -184,6 +201,7 @@ def set_blur_fps(*_): send_mouse_move=True, mouseenter=set_focus_fps, mouseleave=set_blur_fps, + event_throttle_ms=int(1000 * self._rca_event_throttle_s), ) if self._populate_view_ui_f is not None: