edub
edub

Reputation: 21

Python: Read vtk file, add data set then write vtk

I have an exisiting vtk file (of a FE mesh, regular hexahedron mesh) and I would like to add a data set to this that I have in Python. Specifically, I would like to add this numpy data set to each node and then visualize it in ParaView.

Any tips on how I can get started on this?

Upvotes: 1

Views: 3462

Answers (2)

edub
edub

Reputation: 21

Thanks for your assistance. Here is how I solved my problem:

import vtk
from vtk.numpy_interface import dataset_adapter as dsa

# Read in base vtk
fileName = "Original.vtk"
reader = vtk.vtkUnstructuredGridReader()
reader.SetFileName(fileName)
reader.Update()
mesh = reader.GetOutput()

# Add data set and write VTK file
meshNew = dsa.WrapDataObject(mesh)
meshNew.PointData.append(NewDataSet, "new data")
writer = vtk.vtkUnstructuredGridWriter()
writer.SetFileName("New.vtk")
writer.SetInputData(meshNew.VTKObject)
writer.Write()

Upvotes: 1

Cory Quammen
Cory Quammen

Reputation: 1263

VTK (and by extension ParaView) has great NumPy integration facilities. For a wonderful overview on these, please see the blog post series starting with Improved VTK – numpy integration].

The important parts are:

  • You need to wrap your VTK data object in an adapter class
  • You add your NumPy array to the wrapped data set

Sketching this out, you can write:

import vtk
from vtk.numpy_interface import dataset_adapter as dsa

dataSet = ...
numpyArray = ...
adaptedDataSet = dsa.WrapDataObject(dataSet)
dataSet.PointData.append(numpyArray, 'arrayname')

If your data were instead associated with cells rather than points, you would change that last line to

dataSet.CellData.append(numpyArray, 'arrayname')

You'll have to be sure that the order of the data in the NumPy array matches the order of points in the hexahedron mesh.

Now, how do you do this in ParaView? You can add a Programmable Filter. The Python environment in which the script set on the Programmable Filter is executed already does this wrapping for you, so you can simplify the script above to:

# Shallow copy the input data to the output
output.VTKObject.ShallowCopy(inputs[0].VTKObject)

# Define the numpy array
numpyArray = ...

# Add the numpy array as a point data set
output.PointData.append(numpyArray, 'arrayName')

In the script above, output is a wrapped copy of the dataset produced by the Programmable Filter, saving you from having to do the wrapping manually. You do need to shallow copy the input object to the output as the script shows.

Upvotes: 2

Related Questions