Skip to content

Python API Comments

Introduction

Warning

These examples only work with VTK Version: 9.3.20240428 or greater.

VTK documentation regarding the new interface can be found here:

The following sections provide you with further comments and links to examples illustrating the new interface.

Initializing a VTK Class

You can initialize the properties of a wrapped VTK class by specifying keyword arguments in the constructor.

Example Name Comments Image
WarpCombustor Note that in the initialization of vtkMultiBlockPLOT3DReader, SetFileName is an alias for SetXYZFileName so you can use file_name instead of xyz_file_name.
ParametricKuenDemo Very useful in regards to the intitialization of vtkSliderRepresentation2D in make_slider_widget(...).

Set/Get Properties of a VTK Class

Instead of SetSomeProperty() or GetSomeProperty() you can just just drop the Set or Get prefix and use the snake case version of the suffix: some_property.

    print(
        f'Cylinder properties:\n   height: {cylinder.height}, radius: {cylinder.radius},'
        f' center: {cylinder.center} resolution: {cylinder.resolution} capping: {cylinder.capping == 1}')

Generally if a VTK class has a Set or Get method then converting the name to snake case will give you the relevant property e.g. for SetResolution() or GetResolution() the wrapped property will be resolution.

However:

ca.GetProperty().SetColor(colors.GetColor3d('Tomato'))

becomes:

ca.property.color=colors.GetColor3d('Tomato')

In the case of GetColor3d() a vtkColor3d class is returned not a vector, tuple or a simple variable.

Multiple connections in a pipeline

A pipeline can have multiple connections.

    (a, b, c) >> d >> e >> f >> g

E.g.

[vtk.vtkSphereSource(), vtk.vtkSphereSource()] >> vtk.vtkAppendFilter()

or

a = vtk.vtkAppendFilter()
vtk.vtkSphereSource() >> a
vtk.vtkSphereSource() >> a

To reset the append filter, you can use any one of these commands:

a.RemoveAllInputConnections(0)
None >> a
[] >> a
() >> a

Note: None >> a can also be used to clear any inputs on the filter a, whether they are multiple connections or not.

Example Name Comments Image
WarpCombustor Three planes are added to a vtkAppendPolyDatafilter.

Multiple outputs from a pipeline

A pipeline can produce multiple outputs. Here, p is a tuple of vtkDataObjects, for example: p: tuple(vtkDataObject, ..., vtkDataObject). Subsequent pipelines can access the individual elements of the tuple.

    p = (a >> b >> c).update().output
    p1 = vtkSomeClass(input_data=p[0]) >> e >> f
    p1 = vtkAnotherClass(input_data=p[1]) >> g >> h
Example Name Comments Image
SolidClip The tuple clipper contains the clipped output as the first element and clipped away output as the second element.

Selecting ports in a pipeline

Ports in a pipeline can be selected using the function select_ports(). See: vtkmodules.util.execution_model

This function is accessed as follows:

from vtkmodules.util.execution_model import select_ports

The possibilities are:

  • select_ports(input_port, algorithm)
  • select_ports(algorithm, output_port)
  • select_ports(input_port, algorithm, output_port)

So in VisualizeDirectedGraph instead of writing:

    arrow_glyph.SetInputConnection(0, graph_to_poly.GetOutputPort(1))
    arrow_glyph.SetInputConnection(1, arrow_source.GetOutputPort())

you can write:

    select_ports(graph_to_poly, 1) >> arrow_glyph
    arrow_source >> select_ports(1, arrow_glyph)

In PBR_Skybox_Anisotropy instead of writing:

        cube_map.SetInputConnection(i, flipped_images[i].GetOutputPort())

you can write:

        flipped_images[i] >> select_ports(i, cube_map)
Example Name Comments Image
BoxClipStructuredPoints Here, port 0 of box_clip is connected to mapper_in and port 1 of box_clip is connected to mapper_out.
PBR_Skybox_Anisotropy Here we use select_ports() in a loop to add images to a cube map as documented above.
VisualizeDirectedGraph In this case, as documented above, select_ports() is used for both input and output.

Updating part of a pipeline

Sometimes we need to update part of a pipeline so that output can be used in other pipelines.

    a >> b >> c >> d
    c.update() # At this point, a and b will also be updated.
    # Use some data from c to build a new object, say v.
    ...
    # Then:
    v >> w >> x
Example Name Comments Image
LineOnMesh One pipeline creates a smoothed dataset. However we need to update smooth_loop in the pipeline so that vtkCellLocator finds cells in order to create the spline.
MeshLabelImageColor We need the smoother error for the scalar range in the mapper. So we create the pipeline and update smoother to get the needed scalar range. Of course, all other pipeline elements feeding into smoother will be updated also.
PineRootDecimation We update the pipeline in this line: (reader >> deci >> connect >> iso_mapper).update(). This allows us to output counts of triangles all in one place.

Reusing a pipeline

Pipelines can be reused.

    # The pipeline to reuse.
    p = (a >> b >> c)
    # Sources for the pipeline.
    s1 = d
    s2 = e
    # Use the pipeline in a functional way.
    p1 = p(s1())
    p2 = p(s2())
Example Name Comments Image
PipelineReuse Here we use the pipeline in a functional way. This allows us to reuse the pipeline, here, p(cone()) returns a data object so any changes to the pipeline afterward would not be automatically propagated to the rendering pipeline. Finally, we use an append filter to combine the cone and cylinder.

Grouping pipelines

Grouping the pipelines into code blocks may improve the readability of the code.

Example Name Comments Image
EnhanceEdges The pipelines are grouped into a single code block. This may make understanding the code easier.

How to handle #defines using data classes

This example, CurvaturesNormalsElevations, is relatively complex in that a single source feeds into two functions generate_gaussian_curvatures(...) and generate_mean_curvatures(...) returning filters, scalar ranges of curvatures and elevation along with the lookup tables. Additionally a text widget and scalar bar widgets are positioned into two viewports. It nicely demonstrates the usage of data classes.

We can initialize nearly all properties of a wrapped VTK class by specifying keyword arguments in the constructor. There are no issues if the properties are True or False or an existing variable or an enum (which is wrapped in Python) e.g.:

color_series = vtkColorSeries(color_scheme=vtkColorSeries.BREWER_QUALITATIVE_SET3)

However, a lot of Set/Get functions in the VTK classes use values defined as #define VTK_SOME_CONSTANT x. Many of these are defined in the vtkCommonCore module, where they were defined as preprocessor macros. So you can usually access most of them this way or use a data class in Python 3.7 or later.

The real advantage of the data class approach is that the defined VTK constants are used instead of meaningless integers or other values and you don't need to search through the various header files to find the definitions.

Example Name Comments Image
VTKDataClasses This snippet defines immutable data classes that can be used in the initialization of VTK classes or to replace the Set/Get functions that set and get these constants.
CurvaturesNormalsElevations A lot of immutable data classes are used in this example

See: Other Wrapped Entities

Python functions and pipelines

A Python function returning a VTK object can be used as the first element of a pipeline.

  • If the function returns None, then the pipeline will never be implemented.
            read_poly_data(pth) >> mapper

Try this example with a .csv file to see what happens.

Example Name Comments Image
ReadAllPolyDataTypesDemo read_poly_data(pth) returns polydata that is fed directly into the mapper.

Pass by Reference

Some VTK methods methods use pass-by-reference to return values back to the caller. Calling these methods from Python requires special consideration, since Python’s str, tuple, int, and float types are immutable.

A reference type is provided via:

from vtkmodules.vtkCommonCore import reference

This is a simple container allowing pass-by-reference.

Example Name Comments Image
DistancePointToLine Here, we need to pass t as a reference to [vtkLine](https://www.vtk.org/doc/nightly/html/classvtkLine.html).DistanceToLine.

See Pass by Reference

Snippets

Here are some code snippets that can be directly dropped into your code.

Python hints

Make a tuple if you have a starred expression

In MultiplePlots we had an expression:

    points.SetColor(*colors.GetColor4ub('Black'))

This can be rewritten as a tuple, using brackets and a comma:

    points.color = (*colors.GetColor4ub('Black'),)

or, even better, by using a tuple constructor to make it more obvious:

    points.color = tuple(colors.GetColor4ub('Black'))