Save PolyData to CSV using vtkDelimitedTextWriter

I have a VTK file containing 83 points, and I’m trying to use the Python VTK module (no Paraview, no NumPy) to save this data as a CSV file. After looking at a variety of examples, I wrote a script which aims to read the VTK file in as vtkPolyData, create a vtkTable from the vtkPolyData, and write the vtkTable to a CSV file.

My problem is that the resulting CSV file is empty. My script is as follows:

import vtk

fileIn  = 'myPoints.vtk'
fileOut  = 'myTable.csv'

reader = vtk.vtkGenericDataObjectReader()
reader.SetFileName(fileIn)
reader.Update()

table = vtk.vtkDataObjectToTable()
table.SetInputConnection(reader.GetOutputPort())
table.SetFieldType(1)  # "point data" = 1
table.Update()

writer = vtk.vtkDelimitedTextWriter()
writer.SetFileName(fileOut)
writer.SetInputConnection(table.GetOutputPort())
writer.Update()
writer.Write()

I am converting the vtkPolyData to vtkTable because vtkDelimitedTextWriter() expects a vtkTable. I learned that the table’s field type is set to Point Data with “1” via the vtkDataObjectToTable documentation.

If you have any thoughts about why the resulting CSV file is empty, or suggestions as to how to export PolyData to CSV correctly, I would be most appreciative.

Since performance is not a concern, there is no need to use VTK IO classes. You can iterate through the points and write the coordinates to file using standard Python file functions.

Thanks so much for the prompt reply, Andras. I wrote the vtkPolyData to CSV using the following code:

import vtk
import csv

fileIn  = 'myPoints.vtk'
fileOut  = 'myTable.csv'

reader = vtk.vtkGenericDataObjectReader()
reader.SetFileName(fileIn)
reader.Update()

point_obj = reader.GetOutput()
points = [point_obj.GetPoint(i) for i in range(int(point_obj.GetNumberOfPoints()))]
with open(fileOut, 'wb') as csvfileout:
    writer = csv.writer(csvfileout)
    writer.writerows(points)

This works well for now with my test data. I will be dealing with lots of I/O with VTK files made up of millions to billions of points in the future.

If performance issues arise, would VTK IO classes be able to replace this code? If so, would (a modified / working version of) the approach I took in my original post be sensible, or is there a better way?

Good news! I was able to solve this using VTK IO classes, as follows:

import vtk
import csv

fileIn  = 'myPoints.vtk'
fileOut  = 'myTable.csv'

reader = vtk.vtkGenericDataObjectReader()
reader.SetFileName(fileIn)
reader.Update()

point_obj = reader.GetOutput()
points = point_obj.GetPoints()

table = vtk.vtkDataObjectToTable()
table.SetInputData(point_obj)
table.Update()
table.GetOutput().AddColumn(points.GetData())
table.Update()

writer = vtk.vtkDelimitedTextWriter()
writer.SetInputConnection(table.GetOutputPort())
writer.SetFileName(fileOut)
writer.Update()
writer.Write()

This has the added benefit of saving other arrays associated with the points along with the points themselves.

It seems the fundamental problem with the code in my original post was using
table.SetInputConnection(reader.GetOutputPort())
…instead of:
table.GetOutput().AddColumn(points.GetData()) for the points, and
table.SetInputData(point_obj) to get data array data (not my original intention, but a bonus)

This code now accepts a VTK file containing Cartesian points (with or without arrays) and generates a CSV with any array information and the point information.

Thanks for the update. It is nice that you figured out csv text file writing. However, note that writing a surface mesh to a text file will most likely be magnitudes slower, and file size will be magnitudes larger, compared to using binary format. If you need to work with files that have millions of points, you probably want to switch to a standard binary mesh file format (such as .stl, .obj, .ply). Readers are available for these formats in most environments.