예제 #1
0
 def SetInteractor(self, interactor):
     CustomInteractorStyle.SetInteractor(self, interactor)
     # The following three events are involved in the actors interaction.
     self.RemoveObservers('RightButtonPressEvent')
     self.RemoveObservers('RightButtonReleaseEvent')
     self.RemoveObservers('MouseMoveEvent')
     self.AddObserver('RightButtonPressEvent', self.OnRightButtonDown)
     self.AddObserver('RightButtonReleaseEvent', self.OnRightButtonUp)
     self.AddObserver('MouseMoveEvent', self.OnMouseMove)
예제 #2
0
class ShowManager(object):
    """ This class is the interface between the renderer, the window and the
    interactor.
    """
    def __init__(self,
                 ren,
                 title='DIPY',
                 size=(300, 300),
                 png_magnify=1,
                 reset_camera=True,
                 order_transparent=False,
                 interactor_style='custom'):
        """ Manages the visualization pipeline

        Parameters
        ----------
        ren : Renderer() or vtkRenderer()
            The scene that holds all the actors.
        title : string
            A string for the window title bar.
        size : (int, int)
            ``(width, height)`` of the window. Default is (300, 300).
        png_magnify : int
            Number of times to magnify the screenshot. This can be used to save
            high resolution screenshots when pressing 's' inside the window.
        reset_camera : bool
            Default is True. You can change this option to False if you want to
            keep the camera as set before calling this function.
        order_transparent : bool
            True is useful when you want to order transparent
            actors according to their relative position to the camera. The
            default option which is False will order the actors according to
            the order of their addition to the Renderer().
        interactor_style : str or vtkInteractorStyle
            If str then if 'trackball' then vtkInteractorStyleTrackballCamera()
            is used, if 'image' then vtkInteractorStyleImage() is used (no
            rotation) or if 'custom' then CustomInteractorStyle is used.
            Otherwise you can input your own interactor style.

        Attributes
        ----------
        ren : vtkRenderer()
        iren : vtkRenderWindowInteractor()
        style : vtkInteractorStyle()
        window : vtkRenderWindow()

        Methods
        -------
        initialize()
        render()
        start()
        add_window_callback()

        Notes
        -----
        Default interaction keys for

        * 3d navigation are with left, middle and right mouse dragging
        * resetting the camera press 'r'
        * saving a screenshot press 's'
        * for quiting press 'q'

        Examples
        --------
        >>> from dipy.viz import actor, window
        >>> renderer = window.Renderer()
        >>> renderer.add(actor.axes())
        >>> showm = window.ShowManager(renderer)
        >>> # showm.initialize()
        >>> # showm.render()
        >>> # showm.start()
        """

        self.ren = ren
        self.title = title
        self.size = size
        self.png_magnify = png_magnify
        self.reset_camera = reset_camera
        self.order_transparent = order_transparent
        self.interactor_style = interactor_style

        if self.reset_camera:
            self.ren.ResetCamera()

        self.window = vtk.vtkRenderWindow()
        self.window.AddRenderer(ren)

        if self.title == 'DIPY':
            self.window.SetWindowName(title + ' ' + dipy_version)
        else:
            self.window.SetWindowName(title)
        self.window.SetSize(size[0], size[1])

        if self.order_transparent:

            # Use a render window with alpha bits
            # as default is 0 (false))
            self.window.SetAlphaBitPlanes(True)

            # Force to not pick a framebuffer with a multisample buffer
            # (default is 8)
            self.window.SetMultiSamples(0)

            # Choose to use depth peeling (if supported)
            # (default is 0 (false)):
            self.ren.UseDepthPeelingOn()

            # Set depth peeling parameters
            # Set the maximum number of rendering passes (default is 4)
            ren.SetMaximumNumberOfPeels(4)

            # Set the occlusion ratio (initial value is 0.0, exact image):
            ren.SetOcclusionRatio(0.0)

        if self.interactor_style == 'image':
            self.style = vtk.vtkInteractorStyleImage()
        elif self.interactor_style == 'trackball':
            self.style = vtk.vtkInteractorStyleTrackballCamera()
        elif self.interactor_style == 'custom':
            self.style = CustomInteractorStyle()
        else:
            self.style = interactor_style

        self.iren = vtk.vtkRenderWindowInteractor()
        self.style.SetCurrentRenderer(self.ren)
        # Hack: below, we explicitly call the Python version of SetInteractor.
        self.style.SetInteractor(self.iren)
        self.iren.SetInteractorStyle(self.style)
        self.iren.SetRenderWindow(self.window)

    def initialize(self):
        """ Initialize interaction
        """
        self.iren.Initialize()

    def render(self):
        """ Renders only once
        """
        self.window.Render()

    def start(self):
        """ Starts interaction
        """
        try:
            self.iren.Start()
        except AttributeError:
            self.__init__(self.ren,
                          self.title,
                          size=self.size,
                          png_magnify=self.png_magnify,
                          reset_camera=self.reset_camera,
                          order_transparent=self.order_transparent,
                          interactor_style=self.interactor_style)
            self.initialize()
            self.render()
            self.iren.Start()

        self.window.RemoveRenderer(self.ren)
        self.ren.SetRenderWindow(None)
        del self.iren
        del self.window

    def record_events(self):
        """ Records events during the interaction.

        The recording is represented as a list of VTK events that happened
        during the interaction. The recorded events are then returned.

        Returns
        -------
        events : str
            Recorded events (one per line).

        Notes
        -----
        Since VTK only allows recording events to a file, we use a
        temporary file from which we then read the events.
        """
        with InTemporaryDirectory():
            filename = "recorded_events.log"
            recorder = vtk.vtkInteractorEventRecorder()
            recorder.SetInteractor(self.iren)
            recorder.SetFileName(filename)

            def _stop_recording_and_close(obj, evt):
                recorder.Stop()
                self.iren.TerminateApp()

            self.iren.AddObserver("ExitEvent", _stop_recording_and_close)

            recorder.EnabledOn()
            recorder.Record()

            self.initialize()
            self.render()
            self.iren.Start()

            # Retrieved recorded events.
            events = open(filename).read()

        return events

    def record_events_to_file(self, filename="record.log"):
        """ Records events during the interaction.

        The recording is represented as a list of VTK events
        that happened during the interaction. The recording is
        going to be saved into `filename`.

        Parameters
        ----------
        filename : str
            Name of the file that will contain the recording (.log|.log.gz).
        """
        events = self.record_events()

        # Compress file if needed
        if filename.endswith(".gz"):
            gzip.open(filename, 'wb').write(asbytes(events))
        else:
            open(filename, 'w').write(events)

    def play_events(self, events):
        """ Plays recorded events of a past interaction.

        The VTK events that happened during the recorded interaction will be
        played back.

        Parameters
        ----------
        events : str
            Recorded events (one per line).
        """
        recorder = vtk.vtkInteractorEventRecorder()
        recorder.SetInteractor(self.iren)

        recorder.SetInputString(events)
        recorder.ReadFromInputStringOn()

        self.initialize()
        self.render()
        recorder.Play()

    def play_events_from_file(self, filename):
        """ Plays recorded events of a past interaction.

        The VTK events that happened during the recorded interaction will be
        played back from `filename`.

        Parameters
        ----------
        filename : str
            Name of the file containing the recorded events (.log|.log.gz).
        """
        # Uncompress file if needed.
        if filename.endswith(".gz"):
            with gzip.open(filename, 'r') as f:
                events = f.read()
        else:
            with open(filename) as f:
                events = f.read()

        self.play_events(events)

    def add_window_callback(self, win_callback):
        """ Add window callbacks
        """
        self.window.AddObserver(vtk.vtkCommand.ModifiedEvent, win_callback)
        self.window.Render()