VTK/Remove VTK 4 Compatibility

From KitwarePublic
< VTK
Jump to navigationJump to search

Summary

One of the main goals of the pipeline re-architecture between VTK 4 and 5 was to move the execution logic from data and process objects to a new set of classes called executives. However, we made certain compromises in order to maintain backwards compatibility with algorithms developed for VTK 4. The most important and damaging of these was keeping the data object as a conduit of meta-data during pipeline passes.

In the old pipeline, algorithms produced meta-data and requests by setting the on the output/input. Something like:

void ExecuteInformation()
{
  this->GetOutput()->SetWholeExtent(...);
}

In VTK 5, the right way of doing this is

int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector* outputVector)
{
  outputVector->GetInformationObject(0)->Set(WHOLE_EXTENT(), ...);
}

However, the old version still works thanks to the compatibility layer. The code to maintain the backwards compatibility leads to several major problems:

  1. Maintainability of executives and data objects: The executive and data object classes need to contain code to copy meta-data between information objects and data objects at the appropriate times. This code is confusing and hard to maintain as we continue to improve the executives.
  2. Subtle bugs that are very hard to debug: When data objects are used as meta-data storage, do we copy the meta-data when copying the data object? The answer is sometimes. This is hard to explain because it requires a good understanding of the pipeline (specially streaming and parallel execution) but believe me it is a major pain.
  3. Circular dependencies: Data objects are still part of the execution. Therefore, they need to know about executives and algorithms. This creates unnecessary circular dependencies among classes and among objects.

We propose to remove this compatibility layer. It has been a long time since VTK 5 was released. Algorithm and application developers had plenty of time to transition their code to the new pipeline and if they have not transitioned, it means that they are not taking advantage of any new functionality.

Proposed Changes

Removal of the backward compatibility layer

This means that there will be no longer vtkSource/vtkProcessObject to subclass from and that all methods to set/get meta-data on vtkDataObject will be removed. All algorithms will have to use the information objects to propagate meta-data and requests.

Removal of data object's dependency on algorithm and executive

Once we make the change above, data object no longer needs to know about algorithms and executives. This is very nice because now we can break Filtering into a DataModel and an ExecutionModel kit (see VTK/Modularization_Proposal). However, it has a big impact on backwards compatibility. Since data objects can no longer know about their producers, the following cannot be:

filter->SetInput(source->GetOutput());

It is hard to quantify but there are probably quite a few applications that use SetInput() instead of SetInputConnection(). Note that the following can still work

filter->SetInput(data_object);

as long as it is not expected to connect the filter to the data_object's producer. I propose that we remove SetInput() and add a new method (SetInputDataObject?) that has the effect of setting a data object as input without connecting the filter to its producer. This would avoid any problems that may come from changing the behavior of SetInput().

Comment by Lorensen: My main concern with the whole proposal is the removal of filter->SetInput(data_object);. It seems that the proposal is to rename it to SetInputDataObject. Why not just leave it be? Developers have had no time to take this change into account. I do agree that filter->SetInput(source->GetOutput()) should be removed since the SetInputConnection() has been recommended for years.


Even though this may have a significant impact on backwards compatibility, I think that it is a change worth making. It will clean up things tremendously and allow us to move forward with data object - algorithm - pipeline in the future (see the Big Picture below). By the way, it would be easy to write a Perl/Python/whatever script to move most of the existing code forward; specially when fixing SetInput(...->GetOutput()).

Remove the RequestDataObject pass

Now that data object is not used to pass meta-data, there is no need for an algorithm to have its input or output before RequestData. We should remove the RequestDataObject pass (which happens before even RequestInformation) and add the automatic output creation capability to the RequestData pass. For the most part, this is a backwards compatible changes. Things that would break:

  • An algorithm can not longer access its input or output in a pass before RequestData
  • GetOutput() would return null before Update() is called

These are small changes that may require some rearranging of existing code but not significant changes. The main advantage is that algorithms, specially readers, no longer need to do a lot of work to figure out their output type before they get to fully execute.

Update()

  • Update() currently returns void, while it could returns the status of the executive
  • Write() should really be called Update() (in Writer object)