Ubuntu18.04下基于ParaView5.6的Python脚本显示vtkUnstructuredGrid报错求助
我来帮你解决这两个问题,先从最简单的直接显示vtkUnstructuredGrid的方法说起,再修复你自定义源类的问题。
方法一:直接显示已创建的
vtkUnstructuredGrid(无需自定义源类) 你最初的代码报错核心原因是:Show方法需要的是ParaView的数据源代理(vtkSMSourceProxy),而不是原生的VTK对象。ParaView的simple模块提供了UnstructuredGrid代理类,可以直接把你手动创建的vtkUnstructuredGrid包装成可被识别的数据源。
完整示例代码:
import numpy as np from paraview.simple import * import paraview.vtk as vtk import paraview.vtk.util.numpy_support as vnp # 定义节点和单元数据 node = np.array( [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0], [0.0, 1.0, 0.0]], dtype=np.float) cell = np.array([[3, 1, 2, 0], [3, 3, 0, 2]], dtype=np.int) NC = cell.shape[0] # 构建原生vtkUnstructuredGrid对象 points = vtk.vtkPoints() points.SetData(vnp.numpy_to_vtk(node)) cells = vtk.vtkCellArray() cells.SetCells(NC, vnp.numpy_to_vtkIdTypeArray(cell)) uGrid = vtk.vtkUnstructuredGrid() uGrid.SetPoints(points) uGrid.SetCells(vtk.VTK_TRIANGLE, cells) # 关键:将原生vtk对象包装成ParaView数据源代理 unstructuredGridSource = UnstructuredGrid(uGrid) # 显示网格并进入交互模式 view = GetActiveViewOrCreate('RenderView') display = Show(unstructuredGridSource, view) Render() Interact()
方法二:修复自定义源类的问题
你的自定义源类思路没问题,但有两个关键错误导致了报错:
- 直接实例化原生VTK算法类:你用
source = MeshSource()创建的是原生VTKPythonAlgorithmBase实例,而Show需要的是ParaView代理对象。通过@smproxy.source装饰的类,需要通过ParaView的simple模块创建实例。 - 代码拼写错误:
RequestData方法里的optput.ShallowCopy少写了一个u,应该是output.ShallowCopy。
修复后的完整代码:
import numpy as np from paraview.simple import * import vtk import vtk.util.numpy_support as vnp from vtkmodules.util.vtkAlgorithm import VTKPythonAlgorithmBase from paraview.util.vtkAlgorithm import smproxy, smproperty, smdomain @smproxy.source(name="MeshSource", label="triangle mesh!") class MeshSource(VTKPythonAlgorithmBase): def __init__(self): print("Initialize the source!") VTKPythonAlgorithmBase.__init__(self, nInputPorts=0, nOutputPorts=1, outputType='vtkUnstructuredGrid') node = np.array( [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0], [0.0, 1.0, 0.0]], dtype=np.float) cell = np.array([[3, 1, 2, 0], [3, 3, 0, 2]], dtype=np.int) NN = node.shape[0] NC = cell.shape[0] points = vtk.vtkPoints() points.SetData(vnp.numpy_to_vtk(node)) cells = vtk.vtkCellArray() cells.SetCells(NC, vnp.numpy_to_vtkIdTypeArray(cell)) self.mesh = vtk.vtkUnstructuredGrid() self.mesh.SetPoints(points) self.mesh.SetCells(vtk.VTK_TRIANGLE, cells) # 初始化点数据 rho = vnp.numpy_to_vtk(np.zeros(NN)) rho.SetName('rho_A') self.mesh.GetPointData().AddArray(rho) def RequestData(self, request, inInfo, outInfo): print("Request the data!") output = vtk.vtkUnstructuredGrid.GetData(outInfo) # 修正拼写错误 output.ShallowCopy(self.mesh) return 1 def UpdatePointData(self, rho): print("Update the point data!") rho_vtk = vnp.numpy_to_vtk(rho) rho_vtk.SetName('rho_A') # 先移除旧数组再添加新数组,避免重复 self.mesh.GetPointData().RemoveArray('rho_A') self.mesh.GetPointData().AddArray(rho_vtk) self.Modified() # 关键:通过ParaView simple模块创建代理实例,而非直接实例化原生类 source = MeshSource() view = GetActiveViewOrCreate('RenderView') display = Show(source, view) # 示例:动态更新点数据 new_rho = np.array([1.0, 2.0, 3.0, 4.0]) # 通过.VTKObject获取底层原生算法实例,调用自定义方法 source.VTKObject.UpdatePointData(new_rho) Render() Interact()
额外说明:
- 用
@smproxy.source装饰类后,ParaView会自动在paraview.simple模块中注册这个源,所以MeshSource()返回的是符合要求的vtkSMSourceProxy对象。 - 如果要调用自定义的
UpdatePointData方法,需要通过source.VTKObject获取底层的原生算法实例,因为source本身是ParaView的代理包装对象。
内容的提问来源于stack exchange,提问作者Huayi Wei
相关产品推荐
相关产品推荐

