Am I misunderstanding how VTK uses vtkInformation in pipelines?

Hello!!!
I’m trying to use vtkInformation to share “metadata” between items in a vtk pipeline. I’m pretty comfortable setting/getting the keys, values etc., but I’ve demonstrated some behavior that surprised me and I’d like some confirmation that what I’m seeing is correct and expected - and that I’m not goofing up…

Here’s a minimal use case. using a vtkSPhereSUrce and an Elevation filter I create a vtkPolyData with two point fields and I set one of the point fields as the active field. When I complete the pipeline and display the sphere, it is colored using the active field. So far, so good.

Now when I grab the vtkInformation object from the vtkPolyData I EXPCTED to see some information objects contaiing the FIELD_ACTIVE_ATTRIBUTE, BOUNDING_BOX etc. but these vtkInformation objects basically have no values set.

I EXPECTED that VTK was using these vtkInformation to control which field the display is colored by, but it seems not? Or am I doing someting wrong in my example (below).

When run, this code generates values of 0, 0, 0, None for the FIELD_ASSOCIATION, FIELD_ATTRIBUTE_TYPE, FIELD_ACTIVE_ATTRIBUTE and BOUNDING_BOX information

# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
from vtkmodules.vtkFiltersCore import vtkElevationFilter
from vtkmodules.vtkFiltersSources import vtkSphereSource
from vtkmodules.vtkRenderingCore import (
    vtkRenderWindow,
    vtkRenderWindowInteractor,
    vtkRenderer,
    vtkActor,
    vtkDataSetMapper,
)

from vtkmodules.numpy_interface import dataset_adapter as dsa

def main():
    # Origin and radius
    origin=[0.,0.,0.]
    radius=0.1

    # Set up a sphere source and set its origina and radius
    sphere = vtkSphereSource()
    sphere.SetCenter(origin[0], origin[1], origin[2])
    sphere.SetRadius(radius)
    sphere.SetPhiResolution(12)
    sphere.SetThetaResolution(12)

    # Create an Elevation filter at the lowest Z extent of the sphere
    # We'll use to create a Point field of distance from every point on the sphere to the plane
    # and we'll use the field to color code the sphere with a fringe
    elevation = vtkElevationFilter()
    elevation.SetInputConnection(sphere.GetOutputPort())
    elevation.SetLowPoint(origin[0], origin[1], origin[2]-radius)
    elevation.SetHighPoint(origin[0], origin[1], origin[2]+radius)

    elevation.Update()
    poly=elevation.GetOutputDataObject(0)
    #poly_np=dsa.WrapDataObject(poly)
    #p_data=poly_np.PointData
    #print('Point Data : {}'.format(p_data.keys()))

    poly.GetPointData().SetActiveScalars('Elevation')
    #poly.GetPointData().SetActiveScalars('Normals')
    poly.ComputeBounds()
    info=poly.GetInformation()

    print('Field Association : {}'.format(info.Get(poly.FIELD_ASSOCIATION())))   
    print('Field Attribute Type : {}'.format(info.Get(poly.FIELD_ATTRIBUTE_TYPE())))     
    print('Field Active Attribute : {}'.format(info.Get(poly.FIELD_ACTIVE_ATTRIBUTE())))
    print('Bounding Box : {}'.format(info.Get(poly.BOUNDING_BOX())))


    # Create a mapper and connect to the output of the elevation filter
    sphere_mapper = vtkDataSetMapper()
    sphere_mapper.SetInputConnection(elevation.GetOutputPort())

    # Create an actor and connect to the  the mapper sphere
    sphere_actor = vtkActor()
    sphere_actor.SetMapper(sphere_mapper)

    # Render window, renderer and interactor
    renderer=vtkRenderer() 
    renwin=vtkRenderWindow()
    renwin.AddRenderer(renderer)
    iren = vtkRenderWindowInteractor()
    iren.SetRenderWindow(renwin)


    # Add the sphere actor and the glyph actor to the renderer
    # This is the renderer extracted from the ExternalVTKWidget that is linked to the Apex graphics system 
    renderer.AddActor(sphere_actor)

    # Render
    iren.Initialize()
    renwin.Render()
    iren.Start()

if __name__=='__main__':
    main()

Hello,

Am I misunderstanding how VTK uses vtkInformation in pipelines?

Yes, the information object used by a vtkDataObject has different keys than the one used in a vtkAlgorithm.

Some information keys like FIELD_* are used in vtkAlgorithm instances to propagate metadata up/down the pipeline. Those keys are not used in the information objects of vtkDataObject.

Some examples of keys used in vtkPolyData’s information object are vtkDataObject.DATA_EXTENT_TYPE, vtkDataObject.DATA_PIECE_NUMBER, vtkDataObject.DATA_NUMBER_OF_PIECES and vtkDataObject.DATA_NUMBER_OF_GHOST_LEVELS.

I’m not sure if there is a document listing the usage of information keys.

Hope this helps.

Thanks Yashwant,

So I can set vtkInformation on the dataset, but unless it’s one of the vtkInfromation that the algorithm is designed to use (like DATA_EXTENT_TYPE etc) it’s more or less going to be ignored by the algorithms.

I was hoping that I could set vtkInformation on a vtkDataObject and recover it downstream in the pipeline, however this doesn’t seem to work - the vtkInformation I add doesn’t survive passage of the vtkDataObject through the algorithm.

Is there any way I can tell VTK to copy vtkInformation from the input to the outut of a vtkAlgorithm?

Or is it recommended to use FieldData instead of vtkInformation for this purpose?

vtkFieldData sounds like a better choice for you as those tend to get shallow/deep copied from inputs to outputs by most filters. If you notice that field data doesn’t persist, please let us know.

1 Like

Thanks Jaswant!!!