Extensible Data Component

From user's Wiki!
Jump to: navigation, search

The extensible data component allows to easily extend the supported data type representations of the framework, like for example a new image data type. As an example, the GIMIAS MITK plugin extends the framework with 3 image classes: vtkImageData, itk::Image and mitk::Image, while CMGUI plugin extends the framework with CMGUI image structure.

The main class of this component is called DataEntity. A DataEntity is a container that stores a pointer to the internal representation of the data object. By using the bridge pattern, the framework can automatically convert between two different representations at run-time. This feature allows creating powerful workflows combining multiple data representations. When a filter is executed, the internal representation is passed to the filter for processing. Another advantage of this approach is that the integration of a new library doesn't need to modify the source code of the library.

Features

A DataEntity has a metadata object that stores additional information like patient information or rendering properties. All this information is implemented using a generic container and automatically serialized using XML format.

Each DataEntity can have one or multiple rendering data for each rendering engine (like MITK or CMGUI). The rendering data is stored as a DataEntity attribute of the DataEntity, encapsulating the data type representation. If possible, the rendering data will reuse the same processing data instance, reducing the amount of allocated memory.

A DataEntity has a list of children DataEntity instances and a father DataEntity. This information will be used by the Data Tree to create a hierarchical structure. A child data use to be a derived data from the parent, processed using a filter.

A DataEntity can store 3D+T data using a generic implementation (MultipleDataEntityImpl) or specific data representations (for example mitk::Image). When using MultipleDataEntityImpl, it contains a set of DataEntity implementations, like VTK image.

How to extend this component?

To extend the framework with a new data type representation (like vtkImageData), new class should be derived from DataEntityImpl. This new class will store a pointer to the data type (vtkSmartPointer<vtkImageData>). To use the automatic conversion feature that allows converting between two data representations (for example itk and vtk image), the methods GetData( ) and SetData() should be implemented. These methods use the generic tag container to store the data between different representations. For example an image buffer pointer will be stored as a tag with the name "ScalarPointer" in the function GetData(). The function SetData() will retrieve the pointer and create a new image representation.

When a DataEntity contains a specific representation (VTK surface mesh) and the data representation needs to be converted to another representation (CMGUI surface mesh), this component will search if there's any registered implementation that supports this type of data. If an implementation is found, Copy() function will be called and the data will automatically be converted. This is useful for creating workflows composed of filters from different processing libraries.

Integrative workflow example

As an example of this component, an integrative workflow has been created, using ITK, MITK, VTK, GIMIAS and Netgen toolkits and using different data types to store the processing data.

Integrative workflow

In this workflow, 3 different plugin interfaces has been used: 3D Slicer, Raw DLL and GIMIAS.

For each step of the workflow, the required input data is different. For example, MITK filters need a mitk::Image as input. The input data is automatically converted to the required type.

These are the different steps of the workflow:

  • Gaussian Blur (ITK): Gaussian blur of an image
  • mitk::ImageToSurfaceFilter (MITK): Convert image to surface mesh
  • vtkWindowedSincPolyDataFilter (VTK): Smooth surface mesh
  • Ring Cut (GIMIAS): Cut a surface mesh using a ring
  • Volume Closing Surface (GIMIAS): Close all holes of a surface mesh
  • Netgen Optimization (NETGEN): Netgen surface mesh optimization

Rendering data

Each rendering data is stored inside a DataEntity using a string as key.

DataEntity::Pointer GetRenderingData( const std::string& name );
void SetRenderingData( const std::string& name, DataEntity::Pointer dataEntity );

For example, to manage the CMGUI rendering data you need to call:

Core::DataEntity::Pointer renDataEntity = dataEntity->GetRenderingData( "CMGUI" );
dataEntity->SetRenderingData( "CMGUI", renDataEntity );

Example code in MITK Plugin

All MITK data has its own DataEntityImpl.

  • MitkContourImpl: Stores a mitk::Contour
  • MITKCuboidImpl: Stores a mitk::Cuboid
  • MitkImageImpl: Stores a mitk::Image
  • MitkPointSetImpl: Stores a mitk::PointSet
  • MitkSignalImpl: Stores a blMitk::Signal
  • MitkSurfaceImpl: Stores a mitk::Surface
  • MitkTransformImpl: Stores a mitk::Transform

To create an MITK data from any processing data you just need to call these code:

// Get rendering data
Core::DataEntity::Pointer renDataEntity = dataEntity->GetRenderingData( "MITK" );
if ( renDataEntity.IsNull() )
{
  renDataEntity = Core::DataEntity::New( Core::PointSetTypeId );
  renDataEntity->SwitchImplementation( typeid( mitk::PointSet::Pointer ) );
}

// Try to copy data ptr if the data type is the same
// Otherwise, try to copy the data
try
{
  renDataEntity->CopyDataPtr( dataEntity );
}
catch (...)
{
  renDataEntity->Copy( dataEntity, gmReferenceMemory );
}
dataEntity->SetRenderingData( "MITK", renDataEntity );


To retrieve the mitk::BaseData pointer, you need to call this function:

mitk::BaseData::Pointer renderingData;
renderingData = Core::RenDataFactory::GetBaseRenderingData( GetSelectedPointsDataEntity( ) );


UML class diagram and source code

You can read implementation details in GmDataHandling and see example implementations in Mesh Editor Plugin, MITK Plugin, Signal Viewer Plugin and CMGUI Plugin.

Here you can find a video showing the execution of a workflow using different toolkits (VTK, ITK, MITK, GIMIAS) and different data types (itk::Image, vtkImageData, vtkPolyData, mitk::Surface and Netgen).

GIMIAS Components

Go back to GIMIAS Architecture