More Pythonic VTK wrapping

The rshift operator overload, when combined with initializing properties through constructor allows for very readable code!

If you had to reproduce testCaseManyAlgorithmsWithUserInput in TestAlgorithmNumberProtocol in VTK python right now, one’d have to write a function, instantiate every one of those filters, name the instances and setup connections. In the new code, it’s much more readable and easier to code and customize.

Just for the sake of a visual comparison, here they are:

Future
Lines of code: 12

# A pipeline object can be reused with different input data objects.
pipeline = (
vtkElevationFilter()
  >> vtkShrinkFilter()
  >> vtkGeometryFilter()
  >> vtkPolyDataConnectivityFilter(color_regions=True, extraction_mode=VTK_EXTRACT_ALL_REGIONS)
  >> vtkPolyDataNormals()
)
cone = vtkConeSource(radius=5, resolution=8, height=2).execute()
print(pipeline.execute(cone))
cylinder = vtkCylinderSource(radius=6, resolution=9, height=3).execute()
print(pipeline.execute(cylinder))

Now
Lines of code: 29

def execute(input):
    elevator = vtkElelvationFilter()
    shrinker = vtkShrinkFilter()
    ugToPolyData = vtkGeometryFilter()
    connectivity = vtkPolyDataConnectivityFilter()
    connectivity.SetColorRegions(True)
    connectivity.SetExtractionMode(VTK_EXTRACT_ALL_REGIONS)
    normals = vtkPolyDataNormals()
    # build pipeline
    elevator.SetInputDataObject(input)
    shrinker.SetInputConnection(0, elevator.GetOutputPort(0))
    ugToPolyData.SetInputConnection(0, shrinker.GetOutputPort(0))
    connectivity.SetInputConnection(0, ugToPolyData.GetOutputPort(0))
    normals.SetInputConnection(0, connectivity.GetOutputPort(0))
    # run
    normals.Update()
    return normals.GetOutput()
# create a cone
cone = vtkConeSource()
cone.SetRadius(5)
cone.SetResolution(8)
cone.SetHeight(2)
print(execute(cone))
# create a cylinder
cylinder = vtkCylinderSource()
cylinder.SetRadius(6)
cylinder.SetResolution(9)
cylinder.SetHeight(3)
print(execute(cylinder))

Another benefit is that vtkAlgorithm(s) are constructed only the first time when the pipeline object is defined. Compare this with the below code snippet, where they are recreated. Of course, you could write a class and store references to the algorithms, but that’s just more complicated and annoying to do in the interpreter.

4 Likes