Trajectory Pipeline
The architecture of the trajectory pipeline is illustrated below:
Fig. 42 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 aQStringList.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
_1to 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 aMFloatPerTrajectoryVertexSupplement.MFloatPerTrajectorySource: Provides aMFloatPerTrajectorySupplement.
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.