[vtk-developers] Some Event handling ideas

Ken Martin ken.martin at kitware.com
Mon Jul 10 16:00:23 EDT 2017


I like that too :-) So what are your thoughts on down casting to access the
properties? e.g.

void handleEvent(vtkEventData *event)
{
  if (event->GetType() == Button)
  {
    vtkButtonEvent *be = static_cast<vtkButtonEvent *>(event);
    be->GetButtonId()
  }

or something else?




On Mon, Jul 10, 2017 at 2:59 PM, David Gobbi <david.gobbi at gmail.com> wrote:

> Hi Ken,
>
> Why not use polymorphism here?  I use an event hierarchy like so:
>
>   Event <- InputEvent <- PointEvent, KeyEvent
>
> I've never used a union; the code that generates the event knows what type
> of event object to instantiate, and the observer methods just get a pointer
> to the event object.  Qt does things similarly.
>
>  - David
>
>
> On Mon, Jul 10, 2017 at 9:15 AM, Ken Martin <ken.martin at kitware.com>
> wrote:
>
>>
>> Lucas and I have been working on VTK's VR support and one issue we bumped
>> into was event handing. VTK's event handling tends to be data light where
>> most events follow this approach
>>
>> 1) event happens
>>
>> 2) we set properties on the interactor such as alt/shift/control key
>> state, mouse position, etc
>>
>> 3) fire the event (with little or no calldata)
>>
>> 4) event handlers query needed properties from the interactor
>>
>> The challenge here is that as more event types are supported, the
>> interactor's state and structure is required to grow to match them.  For
>> example with multitouch events, the interactor now has to support multiple
>> mouse positions and pointer indexes. Now add in multi controller VR and we
>> have to also store arrays of world coordinate positions and orientations
>> and what controller the current event corresponds to.
>>
>> Many systems use a different approach where they define an event data
>> structure or class that get passed with the event (or associated with the
>> event). Then whatever is handling the event receives that data structure
>> which contains most of the key properties of the event.  Such an event
>> structure can also be used for filtering. For example currently in VTK you
>> can map keyboard events on a widget using the vtkWidgetCallbackMapper method
>>
>> void SetCallbackMethod(unsigned long VTKEvent, int modifiers, char
>> keyCode,
>>                          int repeatCount, const char* keySym,
>>                          unsigned long widgetEvent,
>>                          vtkAbstractWidget *w, CallbackType f);
>>
>> Note that this signature is designed for keyboard events as it contains
>> keyboard event specific parameters. To add a mapping for multitouch, or VR
>> controller events would require more event specific signatures. In contrast
>> if we had a formal vtkEventData structure then the method could use a
>> vtkEventData as a filter and handle many different event types as long as
>> the EventData has an equality operator on it (or maybe a filtering specific
>> equality).
>>
>> Lucas and I have tried this out for VR and it has made event handling
>> reasonable and fairly clean and I would like to get some feedback on the
>> idea/approach/etc.  Right now our vtkEventData is included below. It uses
>> the approach of a union of event type structs and what has been fleshed out
>> is targeted at VR but it should be easy to see how keyboard or mouse
>> devices/events could get added as well.
>>
>> Thanks!
>> Ken
>>
>>
>>
>> enum class vtkEventDataDevice {
>>   Unknown = -1,
>>   HeadMountedDisplay,
>>   RightController,
>>   LeftController,
>>   NumberOfDevices
>> };
>>
>> const int vtkEventDataNumberOfDevices =
>>   static_cast<int>(vtkEventDataDevice::NumberOfDevices);
>>
>> enum class vtkEventDataDeviceInput {
>>   Unknown = -1,
>>   Trigger,
>>   TrackPad,
>>   Grip,
>>   ApplicationMenu,
>>   NumberOfInputs
>> };
>>
>> const int vtkEventDataNumberOfInputs =
>>   static_cast<int>(vtkEventDataDeviceInput::NumberOfInputs);
>>
>> enum class vtkEventDataAction {
>>   Unknown = -1,
>>   Press,
>>   Release,
>>   NumberOfActions
>> };
>>
>> struct vtkEventDataButton3D
>> {
>>   vtkEventDataDevice Device;
>>   vtkEventDataDeviceInput Input;
>>   vtkEventDataAction Action;
>>   double WorldPosition[3];
>>   double WorldOrientation[4];
>>
>>   bool operator==(const vtkEventDataButton3D& rh)
>>   {
>>     return (Device == rh.Device && Input == rh.Input && Action ==
>> rh.Action);
>>   }
>>   void SetWorldPosition(const double p[3])
>>   {
>>     WorldPosition[0] = p[0];
>>     WorldPosition[1] = p[1];
>>     WorldPosition[2] = p[2];
>>   }
>>   void SetWorldOrientation(const double p[4])
>>   {
>>     WorldOrientation[0] = p[0];
>>     WorldOrientation[1] = p[1];
>>     WorldOrientation[2] = p[2];
>>     WorldOrientation[3] = p[3];
>>   }
>> };
>>
>> struct vtkEventDataMove3D
>> {
>>   vtkEventDataDevice Device;
>>   double WorldPosition[3];
>>   double WorldOrientation[4];
>>
>>   bool operator==(const vtkEventDataMove3D& rh)
>>   {
>>     return (Device == rh.Device);
>>   }
>>   void SetWorldPosition(const double p[3])
>>   {
>>     WorldPosition[0] = p[0];
>>     WorldPosition[1] = p[1];
>>     WorldPosition[2] = p[2];
>>   }
>>   void SetWorldOrientation(const double p[4])
>>   {
>>     WorldOrientation[0] = p[0];
>>     WorldOrientation[1] = p[1];
>>     WorldOrientation[2] = p[2];
>>     WorldOrientation[3] = p[3];
>>   }
>> };
>>
>> typedef union
>> {
>>   vtkEventDataButton3D Button;
>>   vtkEventDataMove3D Move;
>> } vtkEventDataUnion;
>>
>> struct vtkEventData
>> {
>>   int Type; // see vtkCommand.h
>>   vtkEventDataUnion Data;
>>
>>   bool operator==(const vtkEventData& rh)
>>   {
>>     if (Type != rh.Type)
>>     {
>>       return false;
>>     }
>>     switch (Type)
>>     {
>>       case vtkCommand::ButtonEvent3D:
>>         return Data.Button == rh.Data.Button;
>>       case vtkCommand::MoveEvent3D:
>>         return Data.Move == rh.Data.Move;
>>     }
>>     return false;
>>   }
>>
>>   bool GetDevice(vtkEventDataDevice &val)
>>   {
>>     switch (Type)
>>     {
>>       case vtkCommand::ButtonEvent3D:
>>         val = Data.Button.Device;
>>         return true;
>>       case vtkCommand::MoveEvent3D:
>>         val = Data.Move.Device;
>>         return true;
>>     }
>>     return false;
>>   }
>>
>>   bool GetWorldPosition(double *&pos)
>>   {
>>     switch (Type)
>>     {
>>       case vtkCommand::ButtonEvent3D:
>>         pos = Data.Button.WorldPosition;
>>         return true;
>>       case vtkCommand::MoveEvent3D:
>>         pos = Data.Move.WorldPosition;
>>         return true;
>>     }
>>     return false;
>>   }
>>
>>   bool GetWorldOrientation(double *&val)
>>   {
>>     switch (Type)
>>     {
>>       case vtkCommand::ButtonEvent3D:
>>         val = Data.Button.WorldOrientation;
>>         return true;
>>       case vtkCommand::MoveEvent3D:
>>         val = Data.Move.WorldOrientation;
>>         return true;
>>     }
>>     return false;
>>   }
>> };
>>
>>
>>
>> --
>> Ken Martin PhD
>> Distinguished Engineer
>> Kitware Inc.
>> 28 Corporate Drive
>> Clifton Park NY 12065
>>
>> This communication, including all attachments, contains confidential and
>> legally privileged information, and it is intended only for the use of the
>> addressee.  Access to this email by anyone else is unauthorized. If you are
>> not the intended recipient, any disclosure, copying, distribution or any
>> action taken in reliance on it is prohibited and may be unlawful. If you
>> received this communication in error please notify us immediately and
>> destroy the original message.  Thank you.
>>
>
>


-- 
Ken Martin PhD
Distinguished Engineer
Kitware Inc.
28 Corporate Drive
Clifton Park NY 12065

This communication, including all attachments, contains confidential and
legally privileged information, and it is intended only for the use of the
addressee.  Access to this email by anyone else is unauthorized. If you are
not the intended recipient, any disclosure, copying, distribution or any
action taken in reliance on it is prohibited and may be unlawful. If you
received this communication in error please notify us immediately and
destroy the original message.  Thank you.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtk-developers/attachments/20170710/0b37b458/attachment-0001.html>


More information about the vtk-developers mailing list