SetOutput data object for non zero port

Is there a way to set the output data object for a non zero port? It appears to me that the standard SetOutput() method can only set the 0th port on an algorithm.

My use case: the vtkBoxClipDataSet filter when GenerateClippedOutputOn() and using port 1 to manage the clipped output:

import vtk
mesh = ... # some data set
alg = vtk.vtkBoxClipDataSet()
alg.SetInputDataObject(mesh)
alg.GenerateClippedOutputOn()
box_clipped_mesh = vtk.vtkUnstructuredGrid()
alg.SetOutput(box_clipped_mesh) 
# How do i set port 1 and not port 0???

You’re not supposed to. I suspect SetOutput lingers from some backwards compatibility API. vtkAlgorithm subclasses will create appropriate output data object as and when needed.

Interesting… so I should avoid using the SetOutput() method and always grab the generated output?

You bet. BTW, remember that repeated execution of the algorithm need not create a new data object instance. It may reuse the one created previously. So if you’re hanging on to the output, you may want to shallow copy it.

When you say “may reuse the one created previously”, is there a chance that the algorithm would ever create a new object?


I’m working on a feature (in PyVista) where I grab the output object of the vtkBoxClipDataSet algorithm upfront before it runs so that I can set up an actor/mapper to show the output in a rendering scene and have the output updated on each execution implemented through callbacks with a box widget.

This is a pseudo-pipeline as I have that dataset added to the rendering scene by setting the input data object (instead of connections) for the mapper/actor. Is there any danger to setting InputDataObjects instead of Connections when pipelining like this?

Yes. Certain filters, like Extract Selection change their output type based on flags set on the filter as well as the input dataset type. There, if the output type changed due to the user toggling some flag on the filter, for example, it will create a new output data object. Generally algorithms reuse output data object unless the type changed, but this is not a requirement.

Setting input data object (by calling vtkAlgorithm::SetInputDataObject or convenience methods e.g. SetInput` provided by subclasses) is totally fine.

This, however, doesn’t sound kosher to me. Instead, what I’d do is create your intended output object and pass that to the mapper. Now, every time you want to update the output via your callback, execute vtkBoxClipDataSet and then shallow copy its output to your intended output object.

Ah, the shallow copy makes sense and something I overlooked. Thanks, @utkarshayachit!