No-Apply Mechanism for Creating Pipelines
The Problem
When creating visualization pipelines in ParaView, the GUI forces the user to hit "Apply" at every stage in the pipeline before another pipeline stage can be added. Thus to create a simple pipeline such as Reader -> Cut, the user has to create the Reader (or open the data file), then hit Apply, then create the Cut filter and hit Apply again. There are a few problems with this approach:
- The intermediate results are rendered. Even if the user had no interest in the output of the reader, he has to wait to see the generated rendering. This is not a huge problem since for really large datasets (based on the settings), this generally leads to rendering only a wireframe.
- The pipeline is not truly demand driven i.e. the reader, since it has no clue what pipelines may be connected, generally ends up reading the full dataset during the first Apply. Even if the Cut filter has means to tell what bounds it's interested in, that information is not available during the first Apply and hence the reader simply has to read everything.
The goal of this proposal is make it possible for the user to build pipelines without having to hit "Apply" or cause execution on the intermediate filters while creating the pipeline.
The Difficulty
Enabling application of filters that don't require use to choose arrays is trivial (that's to the recent cleanup in the ServerManager code that made things called OutputPorts less precarious than before). In fact following some minor tweaks, we can easily enable filters such as Clip (not w/ scalar), Cut, Shrink working. The problem comes with filters that want the user to choose arrays. Without having executed the filter/reader, how does the GUI get information about array available? We can ignore the ranges: we ensure that all user interface components where user puts values in a range, the user is able to enter values beyond the current range, and that pretty much solves our problem (this is mostly the case already, to handle the case where ranges change over time, however some filters e.g. Extract VOI seem to have minor issues). But we need the array names/number of components information.
One could say, if the information is not available, we just let the user enter the array names in a text-box, but that would be very cumbersome to use. Even though the user may know the arrays to expect, they can generally be named in a non-human-friendly form, prone to typos and misspellings.
Also note that some filters may generate new arrays of a known name e.g. Elevation, while others may generate new array whose name depends on a property of the filter itself, e.g. Calculator, and still others may generate new arrays based on input arrays/arraynames as well as properties on the filter eg. point-data-to-cell-data, cell derivatives. All these cases need to be handled gracefully otherwise we will run into usability issues that would be hard to overlook.
Providing the meta-data
First we will need to add support to all readers to start providing meta-data about the arrays that they would read. Most readers already do that, since they present the user with a selection list where the user can choose the arrays to load. They now need to put that information in information keys in their RequestInformation stage of the VTK pipeline.
Now, currently this meta-data also needs to update promptly as the user updates the array-selection on the properties panel for the GUI. That poses an interesting challenge. We don't push the changes to properties to the server (or VTK side) until the user hits apply. So how can we do this?
One proposal was to implement all this logic on the client-side in the server-manager layer itself. But it becomes very cumbersome to provide this logic in xml configuration, for example. Plus this logic can be quite elaborate. The VTK filter is the best location to put this logic.
Hence, this proposal makes a suggestion to change the semantics of Apply all together.
Say Hello to the Execute button
We propose that Apply and Reset buttons disappear. Time and again we have debated the need for Apply/Reset and time and again we have not convinced ourselves one way or the other. One strong reason for Apply button is the fact that rendering/processing cannot be interrupted. That's a whole new can of worms, so we don't deal with that here. Instead, we add an "Execute" button, and ensure that rendering or processing pipelines are not executed unless one hit "Execute". Of course, we will support Auto-Execute mode, similar to the current Auto-Apply mode.
As user changes properties on the panel, they are immediately pushed to the server. Almost like what happens in Python shell. Since the properties are pushed, filters/sources can then provide meta-data in their RequestInformation pass appropriately.
The undo-redo mechanism helps the user to undo any changes he may have accidentally done as before.
Once the user has changed all parameters he wants to, he hits "Execute" and the pipeline executes.
Whenever the user "Executes" after create new filters/sources, only those newly created sources that don't have any consumers connected to them will be displayed in the active view.
(Next section should have been "Say Hello Again to the UpdateSupressors", but that's mostly an inside joke and will only confuse everyone, I am going to control myself).
Data Information
The widgets in the GUI that show arrays lists, for example, rely on domain which in turn rely on data-information provided by the filters. Our goal here is to provide reasonable data-information even when no valid data is available. vtkPVDataInformation class will need to be updated to get information either from the meta-data or the real data, if available. Also as the parameters change, we need fetch data-information from the server. We need to ensure that we only fetch it from the root node since meta-data is similar on all nodes. Domains use this updated data-information to ensure that all combo-boxes list arrays correctly.
Only this missing from this meta-data based information is the array ranges. Also, for composite-datasets, we possibly won't have information about partial arrays or individual blocks.
GUI Widgets
It's absolutely critical that all "range" widgets accept invalid/inaccurate ranges and allow users to enter values beyond those ranges. We had been debating if the ability to manually type array names is useful at all, however, if we ensure that the meta-data provided is fairly reasonable, then there will never be a need for the user to enter names manually, so we can punt on it.
Extending the VTK pipeline
With this mechanism in place, we can envision a purely demand-driven future, where the consumers can request the arrays they need, and producers can provide what's needed on demand. Of course, this proposal doesn't go as far, but it surely doesn't preclude that from happening in the future.