[vtkusers] Trackball style ('t') interaction with QVTKRenderWindowInteractor behaves strange

Elvis Stansvik elvis.stansvik at orexplore.com
Mon Jun 20 05:12:01 EDT 2016


2016-06-16 14:39 GMT+02:00 Elvis Stansvik <elvis.stansvik at orexplore.com>:

> 2016-06-16 14:37 GMT+02:00 Elvis Stansvik <elvis.stansvik at orexplore.com>:
>
>> Launching QVTKRenderWindowInteractor.py as a script, which brings up the
>> built-in cone example, if I hit 't' to switch to trackball style
>> interaction and then rotate the camera around for a few seconds, when I
>> release the mouse there's a noticable delay before the movement stops.
>>
>> The delay seems related to the time the interaction went on: If I rotate
>> around for a longer period, the period between releasing the mouse and the
>> movement finally stopping is longer.
>>
>> Any idea what might be going on here?
>>
>
This is now becoming a real problem, since I see the same behavior in a
custom interactor style I'm working on.

Here's the relevant part of the code:


class InteractorStyle(vtkInteractorStyleUser):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # To ensure GetCurrentRenderer() returns the relevant renderer in
the handlers
        # below, set the current renderer to the one found poked by the
interactor when
        # the mouse moves or a mouse button is pressed.
        for event in [
                vtkCommand.MouseMoveEvent,
                vtkCommand.LeftButtonPressEvent,
                vtkCommand.RightButtonPressEvent,
                vtkCommand.MiddleButtonPressEvent]:
            self.AddObserver(event,
                             lambda *_: self.SetCurrentRenderer(
                                 self.GetInteractor().FindPokedRenderer(
                                     self.x(), self.y())))

        # Hook up event callbacks.
        for event, callback in [
                (vtkCommand.MouseMoveEvent, self.onMouseMoveEvent),
                (vtkCommand.LeftButtonPressEvent,
self.onLeftButtonPressEvent),
                (vtkCommand.LeftButtonReleaseEvent,
self.onLeftButtonReleaseEvent),
                (vtkCommand.RightButtonPressEvent,
self.onRightButtonPressEvent),
                (vtkCommand.RightButtonReleaseEvent,
self.onRightButtonReleaseEvent),
                (vtkCommand.MiddleButtonPressEvent,
self.onMiddleButtonPressEvent),
                (vtkCommand.MiddleButtonReleaseEvent,
self.onMiddleButtonReleaseEvent),
                (vtkCommand.KeyPressEvent, self.onKeyPressEvent),
                (vtkCommand.KeyReleaseEvent, self.onKeyReleaseEvent),
                (vtkCommand.CharEvent, self.onCharEvent),
                (vtkCommand.ExposeEvent, self.onExposeEvent),
                (vtkCommand.EnterEvent, self.onEnterEvent),
                (vtkCommand.LeaveEvent, self.onLeaveEvent),
                (vtkCommand.ConfigureEvent, self.onConfigureEvent),
                (vtkCommand.TimerEvent, self.onTimerEvent),
                (vtkCommand.UserEvent, self.onUserEvent)]:
            self.AddObserver(event, callback)

    def onMouseMoveEvent(self, sender, event):
        pass

    def onLeftButtonPressEvent(self, sender, event):
        pass

    def onLeftButtonReleaseEvent(self, sender, event):
        pass

    def onRightButtonPressEvent(self, sender, event):
        pass

    def onRightButtonReleaseEvent(self, sender, event):
        pass

    def onMiddleButtonPressEvent(self, sender, event):
        pass

    def onMiddleButtonReleaseEvent(self, sender, event):
        pass

    def onKeyPressEvent(self, sender, event):
        pass

    def onKeyReleaseEvent(self, sender, event):
        pass

    def onCharEvent(self, sender, event):
        pass

    def onExposeEvent(self, sender, event):
        pass

    def onEnterEvent(self, sender, event):
        pass

    def onLeaveEvent(self, sender, event):
        pass

    def onConfigureEvent(self, sender, event):
        pass

    def onTimerEvent(self, sender, event):
        pass

    def onUserEvent(self, sender, event):
        pass

    def x(self):
        """Current event X position"""
        return self.GetInteractor().GetEventPosition()[0]

    def y(self):
        """Current event Y position"""
        return self.GetInteractor().GetEventPosition()[1]

    def lastX(self):
        """Last event X position"""
        return self.GetInteractor().GetLastEventPosition()[0]

    def lastY(self):
        """Last event Y position"""
        return self.GetInteractor().GetLastEventPosition()[1]

    def control(self):
        """Control modifier?"""
        return self.GetInteractor().GetControlKey()

    def shift(self):
        """Shift modifier?"""
        return self.GetInteractor().GetShiftKey()


class CloseUpInteractorStyle(InteractorStyle):

    # States
    Idle = 0
    Panning = 1
    Rotating = 2
    Tumbling = 3
    Zooming = 4

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.state = self.Idle

    def onLeftButtonPressEvent(self, sender, event):
        if self.GetCurrentRenderer() is None:
            return

        self.state = self.Rotating

    def onLeftButtonReleaseEvent(self, sender, event):

        self.state = self.Idle

    def onMouseMoveEvent(self, sender, event):
        if self.GetCurrentRenderer() is None:
            return

        if self.state == self.Rotating:
            self._rotate()

    def _rotate(self):
        if self.GetCurrentRenderer() is None:
            return

        dx = self.x() - self.lastX()

        renderer = self.GetCurrentRenderer()
        interactor = self.GetInteractor()

        (windowWidth, _) = renderer.GetRenderWindow().GetSize()
        azimuth = -200.0 * dx / windowWidth

        print('azimuth: {}'.format(azimuth))
        camera = renderer.GetActiveCamera()
        camera.Azimuth(azimuth)
        camera.OrthogonalizeViewUp()

        interactor.Render()

The InteractorStyle class is just a helper base class I use for custom
interactor styles, it observes all events on itself and calls corresponding
methods (to be overridden).

The CloseUpInteractorStyle is my basic interactor style embryo. All it does
is handle click + horizontal movement of the mouse by setting the azimuth
of the camera.

The same strange "lagging" behavior can be observed when click-moving the
mouse somewhat rapidly for a few seconds.

I'm attaching the full code, which also includes VTKWidget, a somewhat
simplified / cut down version of QVTKRenderWindowInteractor I'm using (by
note that I'm seeing the same problem with an unmodified
QVTKRenderWindowInteractor).

Is the rendering not keeping up with the rate of the mouse events? Do I
need to perform some kind of event compression manually?

Any advice is much appriciated!

Elvis


> When using the joystick style ('j', the default) the behavior is normal.
> Movement stops as soon as the mouse button is released.
>
> Elvis
>
>
>> Elvis
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160620/6690a7b1/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: vtk_widget.py
Type: application/x-download
Size: 15837 bytes
Desc: not available
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160620/6690a7b1/attachment.bin>


More information about the vtkusers mailing list