1. Data-flow Paradigm

Data Flow

The design of the Voreen framework revolves around the concept of data-flow networks.

These networks consist of modular units, called processors, which encapsulate rendering and data processing algorithms. A processor operates on input data it receives from its inports and outputs the processed results via its outports.

The data-flow is established by unidirectional connections from outports to inports. Processor ports are typed, i.e., each port transmits a certain type of data, such as a 2D image, a 3D volume, geometric data, or a collection of objects of these basic types. Processors furthermore have properties for the parameterization of the encapsulated algorithms. Voreen offers various types of properties ranging from primitive numeric types to complex rendering parameters, such as camera position and transfer function. Properties can be linked within and across processors, in order to synchronize their values.

The strength of the data-flow concept lies in the flexible combinability of components. Since a processor's behaviour is solely determined by its input data and property configuration, processors can be arbitrarily joined into networks with the only restriction that connected ports need to be of equal type. Moreover, there is no distinction made between standard processors provided by the framework and custom processors created by external developers. This allows developers to completely focus on implementing new techniques, while utilizing standard framework processors for common data processing, rendering, and user interaction tasks.

1.1 User Interface

The Voreen framework provides a graphical network editor that enables the user to interactively design data-flow networks from existing processors without writing a single line of code. In particular, the user can manipulate the network topology by adding or removing processors, establishing or deleting port connections, and editing property links. Furthermore, processors can be aggregated to higher-level groupings.

For a convenient parameterization of processors, property widgets are automatically generated for each property in a network. In the usual application case, this completely frees processor developers from the burden of GUI programming. Only custom property types, which are rarely actually necessary, require the developer to implement a corresponding property widget.

The network editor and the property widgets are embedded in the Qt-based VoreenVE (visualization environment) application. It also provides GUI tools for the inspection of intermediate data processing results, performance analysis, animation recording, and Python scripting.

2. Project Structure

2.1 Framework

The Voreen framework uses a multi-layer architecture for a clean separation of the rendering back-end from the GUI layer.

Voreen Arch

The VoreenCore library contains central data structures and resource management functionality. It does not have any GUI toolkit dependencies and is specifically designed to be easily embeddable into external applications. Its header and source files are located in include/voreen/core and src/core, respectively.

The VoreenQt library provides Qt-based GUI components, mainly processor and property widgets, as well as factory mechanisms for the automatic instantiation of these widgets. The library might also be employed by an external application, but its use is optional. The code files are located in include/voreen/qt and src/qt.

The VoreenVE GUI application located in apps/voreenve links against both the VoreenCore and VoreenQt libraries. The VoreenTool application (apps/voreentool) provides a command-line interface to the VoreenCore library. The Simple-GLUT application (apps/simple/simple-glut) is a basic example of a Voreen GUI application without Qt dependency.

2.2 Modules

As stated above, the framework itself contains only data structures, base classes, and management components. All active components are assembled in Voreen modules. On the core level, these modules may contain implementations of the three data-flow components, namely processors, ports, and properties, but also data readers/writers or supplementary code. The components provided by a module are integrated into the framework on two different levels. Code files are incorporated into the build process by a CMake file. At runtime, the module's resources are registered by a subclass of VoreenModule, which instantiates the module's classes using a factory pattern. For detailed instructions on how to add a custom module, please refer to the module tutorial.

Besides the core library, the GUI layers are also extendable by modules. This is, however, less common, since the framework already supplies a wide variety of Qt widgets for representing processors and properties in the user interface. VoreenQt modules contain custom property or processor widgets. VoreenVE plugins are presented as a tool widget in the VoreenVE application and have access to the entire data-flow network.