如何在 Paraview 中渲染一个简单的 2D vtkImageData 对象?

How to render a simple 2D vtkImageData object in Paraview?

我想使用 Paraview 绘制简单的 2D 网格,每个单元格使用不同颜色或每个顶点使用不同颜色。据我所知,Paraview 文档没有解释如何 Show() 用户定义的 VTK 对象。

我从 Paraview guide how the VTK data model works and from the VTK User's Guide 中了解到如何生成 vtkImageData 对象。

据我所知,以下代码应该生成一个 vtkImageData 的 10x5 二维网格对象,跨越 [0.;10.]x[0.;5.],包含 50 个蓝色元素。

但现在我不知道如何在 Paraview 中实际绘制它。

from paraview import vtk
import paraview.simple as ps
import numpy as np
from paraview.vtk.util.numpy_support import numpy_to_vtk

def main():
    # create the vtkImageData object
    myMesh = vtk.vtkImageData()
    myMesh.SetOrigin(0.,0.,0.)
    myMesh.SetExtent(0,10,0,5,0,0)
    myMesh.SetSpacing(1.,1.,0.)

    # create the numpy colors for each cell
    blue = np.array([15, 82, 186], dtype=np.ubyte)  # 8 bits each [0, 255]
    npColors = np.tile(blue, (myMesh.GetNumberOfCells(), 1))

    # transform them to a vtkUnsignedCharArray
    # organized as 50 tuples of 3
    vtkColors = numpy_to_vtk(npColors, deep=1, array_type=vtk.VTK_UNSIGNED_CHAR)

    # allocate the sets of 3 scalars to each cell
    myMesh.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 3)  # set 3 scalars per cell
    myMesh.GetCellData().SetScalars(vtkColors)  # returns 0, the index to which
                                                # vtkColors is assigned
    # Something... generate a proxy using servermanager??

    ps.Show(myMesh?)
    ps.Interact()  # or ps.Render()

if __name__ == "__main__":
    main()

据我所知,我必须先应用几何滤镜,例如 vtkImageDataGeometryFilter()。但是paraview.vtk中没有这个,只能直接导入vtk模块。

根据 的另一种选择是使用 vtkMarchingSquares

无论哪种方式,显然 paraview.simple.Show 只接受代理对象作为输入。这又引出了如何从过滤后的 vtkImageData 对象创建代理的问题?老实说,尽管阅读了文档,但我还不太了解可视化管道的工作原理。

到目前为止,我只找到了直接通过 Kitware examples in GitHub 使用 vtk 可视化 VTK 对象的方法,而不使用 Paraview 的高级功能。

ProgrammableSource 就是你要用的。参见 this example or this

我设法使用 TrivialProducer 对象和方法 .GetClientSideObject() 来呈现它。这将 ParaView 连接到服务器端对象。

来源:the source code and the tip given by Mathieu Westphal 来自 ParaView 支持。

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()