Trajectory Pipeline

The architecture of the trajectory pipeline is illustrated below:

A schematic of the trajectory pipeline.

Fig. 34 Trajectory pipeline schematic.

Point Generating Sources

The MPointGeneratorSource generates a list of points packed into a MPoints data item, managed in memory. It requests a MPointGeneratorInterface to generate the points. The horizontal cross-section and vertical cross-section actors implement this interface and provide the necessary methods for point generation based on the actor’s current state and user interface.

To implement a custom point source, have the class inherit from MPointGeneratorInterface and implement the following abstract methods:

  • QString getPointGeneratingSourceBaseRequestKeys(): Generates a clear, identifiable string based on its current state (e.g., current slice position) and user interface. This string should consistently yield the same set of generated points in the subsequent method.

  • MPoints* generatePointsFromString(const QString&): Generates the data item containing the list of points based on the provided request string.

Register the interface with MPointSourceFactory in the constructor, e.g.:

MPointSourceFactory::getInstance()->registerPointGeneratingInterface<MPointGeneratorInterfaceSettings>(this);

The template argument must be a class inheriting from MPointGeneratorInterfaceSettings, containing the user interface settings.

Remember to deregister the interface upon deletion. Use MPointSourceFactory::showCreationDialog() to display a dialog allowing the user to select a point generation interface from the registered ones.

Point Filters

Point filters inherit from MPointFilter and accept a MPoints data item as input, returning an altered MPoints data item. Each filter has a MPointSource as its parent, which may be either a MPointGeneratorSource or another MPointFilter.

To create a new point filter, inherit from MPointFilter, implement the necessary methods and functionality, and register it in the MPointFilterFactory::MPointFilterFactory() constructor. You need to implement:

  • produceData(): Contains the filtering heuristic.

  • getFilterName(): Returns the general display name of the filter.

  • getBaseRequestKeys(): Returns the base keys for data requests as a QStringList.

    Note

    The keys returned should be unique for the filter type, not for specific instances. Met.3D generates unique identifiers for data requests from these base keys, allowing multiple instances of the same filter in one pipeline without conflicts. Met.3D manages registered filters and assigns unique request identifiers for them, e.g., by appending _1 to the filter’s base request identifier.

Like point sources, a user interface class inheriting from MPointFilterSettings is required to describe the UI and handle settings for the filter. Refer to existing filters for examples.

Trajectory Sources

Precomputed trajectories are loaded via MTrajectoryReader, while on-the-fly computed trajectories are generated through MTrajectoryComputationSource. The computation process is encapsulated in the MTrajectoryComputation class. Trajectory sources return a MTrajectories data item, containing the vertex data of the trajectories along with some metadata.

Trajectory Filters

As shown in the schematic above, trajectory filters are connected downstream to the trajectory source. A MTrajectoryFilter processes input from both MTrajectoryDataSource (the trajectories) and MTrajectorySelectionSource (the trajectory selection), returning a trajectory selection. These filters can:

  • Discard entire trajectories.

  • Discard segments of trajectories.

Currently implemented trajectory filters include:

  • Trajectory ascent and descent filter,

  • Trajectory bounding box filter,

  • Trajectory thin-out filter.

Single Point Filter

The MSingleTimeTrajectoryFilter extracts single time position data from the trajectories, used for rendering spheres at points in time selected in the user interface. It returns a MWritableTrajectorySelection, but specifically includes only subsets of trajectories with length 1.

Normals Source

The MTrajectoryNormalsSource computes normal directions along all trajectories, essential for accurate rendering and shading. The returned data item is a MTrajectoryNormals.

Note

Normal directions depend on the vertical scale of the scene. Thus, normals must be computed separately for each scene, resulting in an additional layer of lists within the MTrajectoryNormals data item: normals per scene view.

Auxiliary Data Sources

Additional data can be computed and included in the trajectory collection, either for individual vertices or entire trajectories. These supplementary data sources include:

  • MFloatPerTrajectoryVertexSource: Provides a MFloatPerTrajectoryVertexSupplement.

  • MFloatPerTrajectorySource: Provides a MFloatPerTrajectorySupplement.

The MAuxiliaryVariableTrajectorySource generates per-vertex data based on auxiliary data fields, enabling trajectory rendering with these fields. Alternatively, the MDeltaPressurePerTrajectorySource demonstrates the float per trajectory source by calculating the maximum pressure change along a trajectory within a specified time interval.

The Trajectory Pipeline Barrier

The MTrajectoryPipelineManager has dual responsibilities: it controls the pipeline, ensuring proper connections between elements (filters, etc.), and it adds new sources and filters as requested. It switches the pipeline structure when changing from a precomputed source to a computational source and vice versa.

Additionally, it functions as a data source gateway for all requested trajectory data, including norms, auxiliary fields, single time positions, etc. In its produceData(), it does not perform calculations directly but aggregates data from all upstream sources in the diagram, encapsulating them in a MTrajectoryDataCollection and returning this collection. This approach informs the requester only after all computations are complete.

Note

Due to the current state of memory management in Met.3D, the MTrajectoryPipelineManager holds no “real” data; instead, the MTrajectoryDataCollection contains references to other data items. It is crucial to ensure that the memory manager does not delete upstream data items before the MTrajectoryDataCollection is deleted. This is currently achieved by not releasing data items in the produceData() method, thus retaining one additional reference to the depended items. Once the data item is deleted in the destructor, it releases those references, allowing their deletion.

The Trajectory Dispatcher

The MTrajectoryRequestDispatcher manages the trajectory pipelines. Each point source is linked to a dedicated pipeline, allowing efficient caching of computation results. When a point source changes, only the points for that source are used to recompute the corresponding trajectories.

Similar to the pipeline, it serves as a barrier, holding references to both the pipeline and the associated data item references to collections returned by the pipelines.