# Support for keyframe based animation

**URL:** <https://discourse.slicer.org/t/support-for-keyframe-based-animation/6885>\
**Category:** Development\
**Created:** [May 21, 2019, 7:32pm UTC](https://discourse.slicer.org/t/support-for-keyframe-based-animation/6885 "2019-05-21T19:32:01Z")\
**Posts on this page:** 1\
**Showing post:** 24

<div class="post-metadata">

**Author:** ![jcfr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jcfr/32/17825_2.png) [@jcfr](https://discourse.slicer.org/u/jcfr)\
**Post date:** [July 9, 2019, 1:52pm UTC](https://discourse.slicer.org/t/support-for-keyframe-based-animation/6885/24 "2019-07-09T13:52:26Z")

</div>

To add support for interpolation and associated UI for key frame edition, here is what I was thinking (based on what we [discussed](https://github.com/NA-MIC/ProjectWeek/tree/master/PW31_2019_Boston/Breakouts/Infrastructure) during the last project week).

## The Key Frame editor

from a high level, I suggest we keep things simple and support the following:

(1) a **master timeline** to drive the animation. (at first we would only have “Real-time” mode where we set the the duration in seconds).

We could reuse the [Drishti](https://github.com/nci/drishti/) widget (MIT License) or the one from Paraview, or an improved version getting the best of both.

- Drishti timeline (I was able to compile it … and it was not straightforward)

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/8/e/8e0bcb593d4ef1bf3a15edb3eaffe5a9b99e4f1d.png)

- Paraview timeline

![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/optimized/3X/f/9/f916863a3fe0f9364f5100dce5d335e6b6cc72c3_2_690x25.png)

(2) three pre-defined tracks:

- camera path

- ROINode (the one allowing to crop volume rendering)

- transfer function

where keyframe can explicitly be added/removed only for ROINode and transfer function

The “camera path” would be defined using an improved version of the endoscopy module (as describe [here](https://discourse.slicer.org/t/support-for-keyframe-based-animation/6885/6)).

## Suggested approach

This section describe a possible way to more forward by updating the sequences modules to be user in Key Frame editor.

See [https://www.slicer.org/wiki/Documentation/Nightly/Extensions/Sequences](https://www.slicer.org/wiki/Documentation/Nightly/Extensions/Sequences)

### Features already available in sequences extension

Given the current sequences implementation where:

- A given `vtkMRMLSequenceNode` is associated with a collection of data nodes.

- A `vtkMRMLSequenceBrowserNode` is associated with a collection of `vtkMRMLSequenceNode`

- The entrypoint for updating all proxy nodes is the function `vtkSlicerSequenceBrowserLogic::UpdateProxyNodesFromSequences`

- The “time steps” available in a given sequence browser corresponds to the number of “items” associated with a browser node, itself corresponding to the number data nodes in the associated master node.

- if a synchronized sequence node (different from the master sequence) doesn’t have a data node corresponding to the requested “step” (call “indexValue” in the code), the closest data node is used to update the proxy node. This is implemented in

We need a way to map:

- the concept of track and key frame with vtkMRMLSequenceNode, vtkMRMLSequenceBrowserNode and data node

- have a container to store time for a key frame, and interpolation function used between two frames

Good news, key frames are data node within a `vtkMRMLSequenceNode`

### Support for interpolation

To support **interpolation** , I was then thinking of the following:

- update the parameter exactMatchRequired from “GetDataNodeAtValue” function to be something like “interpolationMode” accepting the following values:

- In case of ExactMatchOrInterpolated mode, if not an exact match GetDataNodeAtValue would have to perform the interpolation (or retrieved a cached value of the interpolated data node)

- the interpolation function would have the following paramerters: fromDataNode, toDataNode, nodeInterpolator, fromTime, toTime and currentTime (or fromStep, toStep and currentStep)

- within each sequence node we would store a vector of “node interpolators”. This would corresponds to the function applies when performing an interpolation between two data nodes.

- update the vtkMRMLNodeSequencer::NodeSequencer base class adding interpolation method : GetInterplatedNode(vtkMRMLNode\* from, vtkMRMLNode\* to, vtkMRMLNodeSequencer::NodeInterpolator\* interpolator, double fromTime, double toTime, double currentTime)

### Reusing Paraview code

I was initially thinking to extract some of the [code of Paraview](https://github.com/Kitware/ParaView/tree/master/ParaViewCore/Animation) and add it to VTK so that we can reuse some in both Slicer and Paraview:

```plaintext
  vtkPVKeyFrame
  vtkPVCompositeKeyFrame
  vtkPVBooleanKeyFrame
  vtkPVSinusoidKeyFrame
  vtkPVExponentialKeyFrame
  vtkPVRampKeyFrame
  vtkPVKeyFrameCueManipulator (and base class vtkPVCueManipulator)
  vtkRealtimeAnimationPlayer
  vtkSequenceAnimationPlayer
  vtkTimestepsAnimationPlayer
  vtkCompositeAnimationPlayer
  vtkSMAnimationScene (investigate if changes can be integrated with vtkAnimationScene)
  Note that vtkAnimationCue and vtkAnimationScene are already part of VTK.

```

But it seems the API available in the sequences module doesn’t really overlap with what was done in Paraview.

---

_[View the full topic](https://discourse.slicer.org/t/support-for-keyframe-based-animation/6885)._
