To add support for interpolation and associated UI for key frame edition, here is what I was thinking (based on what we discussed 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 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)
(2) three pre-defined tracks:
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).
This section describe a possible way to more forward by updating the sequences modules to be user in Key Frame editor.
Features already available in sequences extension
Given the current sequences implementation where:
vtkMRMLSequenceNode is associated with a collection of data nodes.
vtkMRMLSequenceBrowserNode is associated with a collection of
The entrypoint for updating all proxy nodes is the function
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
vtkMRMLSequenceNode::GetItemNumberFromIndexValue(const std::string& indexValue, bool exactMatchRequired /* =true */)
vtkMRMLSequenceNode::GetDataNodeAtValue(const std::string& indexValue, bool exactMatchRequired /* =true */)
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
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 and add it to VTK so that we can reuse some in both Slicer and Paraview:
vtkPVKeyFrameCueManipulator (and base class vtkPVCueManipulator)
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.