How does one create a simple 2D mesh plot using ParaView from a vtkImageData object. This type of object is mentioned in the ParaView Guide in “3. Understanding data”, but it is never shown how to use use it directly.
import numpy as np
from paraview import vtk, simple
from paraview.vtk.util.numpy_support import numpy_to_vtk
from vtk import vtkImageDataGeometryFilter # this isn't in paraview.vtk
# Create an image (this is a data object)
myMesh = vtk.vtkImageData()
myMesh.SetOrigin(0., 0., 0.)
myMesh.SetSpacing(0.01, 0.01, 0.)
myMesh.SetExtent(0, 100, 0, 50, 0, 0)
# coloring
blue = np.array([15, 82, 186], dtype=np.ubyte)
# numpy colors
scalarsnp = np.tile(blue, (myMesh.GetNumberOfCells(), 1))
# vtk array colors. Organized as 50 tuples of 3
scalarsvtk = numpy_to_vtk(scalarsnp, deep=1, array_type=vtk.VTK_UNSIGNED_CHAR)
# allocate the scalars to the vtkImageData object
# Not sure why the following line is not necessary (tested using VTK)
# myMesh.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 3) # set 3 scalars per cell
myMesh.GetCellData().SetScalars(scalarsvtk)
# generate a vtkPolyData from the vtkImageData
myMeshPD = vtkImageDataGeometryFilter()
myMeshPD.SetInputData(myMesh)
# more code...
simple.Show(??)
simple.Interact() # or simple.Render()
Now if I were to use pure VTK, I’d create a mapper, an actor and render everything to a window.
The question is, at which point of the above pipeline is it possible to use Paraview, if at all?
From my very limited understanding on the subject, I think it is possible to generate a proxy out one of the aforementioned objects (using paraview.servermanager maybe?) and then use paraview.simple.Show. But I am not sure and am completely lost in the Paraview documentation.
I’ve successfully rendered the mesh in ParaView! Instead of vtkImageDataGeometryFilter, I can use vtkTextureMapToPlane, or rather TextureMaptoPlane from paraview.simple.
Though, I think I might have found a bug in version 5.9.1.
A minimum working example (which could be used for a github/paraview/examples page, sort of like VTK):
from paraview import simple as ps
from paraview import vtk
from paraview.vtk.util.numpy_support import numpy_to_vtk
import numpy as np
def main():
# Create an image (this is a data object)
myMesh = vtk.vtkImageData()
myMesh.SetOrigin(0., 0., 0.)
myMesh.SetSpacing(0.1, 0.1, 0.)
myMesh.SetExtent(0, 10, 0, 5, 0, 0)
# coloring
blue = np.array([15, 82, 186], dtype=np.ubyte)
# numpy colors
scalarsnp = np.tile(blue, (myMesh.GetNumberOfCells(), 1))
scalarsnp[[9, 49]] = np.array([255, 255, 0], dtype=np.ubyte) # yellow
# vtk array colors. Organized as 50 tuples of 3
scalarsvtk = numpy_to_vtk(scalarsnp, deep=1, array_type=vtk.VTK_UNSIGNED_CHAR)
scalarsvtk.SetName("colorsArray")
# allocate the scalars to the vtkImageData object
# myMesh.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 3) # set 3 scalars per cell
# myMesh.GetCellData().SetScalars(scalarsvtk) # do not use this in ParaView!!
colorArrayID = myMesh.GetCellData().AddArray(scalarsvtk)
myMesh.GetCellData().SetActiveScalars(scalarsvtk.GetName())
# TrivialProducer to interface ParaView to serverside objects
tp_mesh = ps.TrivialProducer(registrationName="tp_mesh")
myMeshClient = tp_mesh.GetClientSideObject()
# link the vtkImageData object to the proxy manager
myMeshClient.SetOutput(myMesh)
tp_mesh.UpdatePipeline()
# Filter for showing the ImageData to a plane
mapTexture2Plane = ps.TextureMaptoPlane(registrationName="TM2P_mesh", Input=tp_mesh)
renderViewMesh = ps.CreateView("RenderView")
renderViewMesh.Background = [1, 1, 1]
renderViewMesh.OrientationAxesVisibility = 0
display = ps.Show(proxy=mapTexture2Plane, view=renderViewMesh)
display.SetRepresentationType("Surface")
display.MapScalars = 0 # necessary so as to not generate a colormap
ps.Interact() # or just ps.Render()
if __name__ == "__main__":
main()
Edited to disable scalar mapping. Also hid the orientation axes.
Before I close this issue, though, it seems that the yellow cells from the above minimum working example are being shown as red instead of yellow. Is there something more to the array orders that I have missed?
After some testing, it seems that the data is not faulty. I am just not using the ParaView filters correctly. It seems to automatically apply a color map instead of assigning the given RGB colors as the face color for each cell. A legacy ASCII VTK file of the imagedata can be found attached. I simplified the blue color to be [0 0 255] for an easier read. ImageData.vtk (519 Bytes)
From what I’ve read in the VTK doxygen, I have to enable the creation of a lookuptable based on the CellData, for the colors. I’m not sure which method I should use for this. And whether it is in the vtkImageData itself, or in the object obtained after applying the filter in ParaView. The class that has this functionality seems to be vtkMapper. Not sure how to use it.