Как показать vtkUnstructuredGrid в скрипте python на основе paraview?

Я устанавливаю paraview 5.6 в свою систему Ubuntu 18.04 и хочу написать скрипт на Python для отображения vtkUnstructuredGrid.

import numpy as np
from paraview.simple import *
import paraview.vtk as vtk
from paraview.vtk.numpy_interface import dataset_adapter as dsa
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]

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)
# how to put uGrid into the following codes
view = GetActiveViewOrCreate('RenderView') 
dispaly = Show()
render = Render()
Interact()

Я не могу найти в Интернете ни одного примера, чтобы сделать это в скрипте Python. Так что мне нужна ваша помощь, большое спасибо.

Обновление:

Я пытаюсь закодировать исходный класс следующим образом:

import numpy as np
from paraview.simple import *
import vtk 
import vtk.util.numpy_support as vnp
from vtkmodules.util.vtkAlgorithm import VTKPythonAlgorithmBase
from vtkmodules.numpy_interface import dataset_adapter as dsa
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)
        self.Port = 0

    def RequestData(self, request, inInfo, outInfo):
        print("Request the data!")
        output = vtk.vtkUnstructuredGrid.GetData(outInfo)
        optput.ShallowCopy(self.mesh)
        return 1

    def UpdatePointData(self, rho):
        print("Update the point data!")
        rho = vnp.numpy_to_vtk(rho)
        rho.SetName('rho_A')
        self.mesh.GetPointData().AddArray(rho)
        self.Modified()

source = MeshSource()
view = GetActiveViewOrCreate('RenderView') 
display = Show(source, view)
Interact()

Но я получил некоторую ошибку:

Traceback (most recent call last):
  File "test_triangle.py", line 55, in <module>
    dispaly = Show(source, view)
  File "/home/why/local/lib/python3.6/site-packages/paraview/simple.py", line 482, in Show
    rep = controller.Show(proxy, proxy.Port, view)
  File "/home/why/local/lib/python3.6/site-packages/paraview/servermanager.py", line 158, in __ConvertArgumentsAndCall
    retVal = func(*newArgs)
TypeError: Show argument 1: method requires a vtkSMSourceProxy, a vtkPythonAlgorithm was provided.

Я должен что-то пропустить.


person Huayi Wei    schedule 09.02.2019    source источник


Ответы (1)


Главное, что нужно понять, это то, что в ParaView доступно два уровня сценариев Python. На нижнем уровне вы можете создавать или фильтровать данные с помощью VTK. Более высокий уровень позволяет вам управлять работой ParaView, например, отображать данные, устанавливать свойства отображения и т. д. Чего вам не хватает, так это моста между двумя уровнями в вашем скрипте.

В вашем исходном примере вы отлично создаете неструктурированную сетку в VTK. Чтобы получить его в месте, где ParaView может его использовать, добавьте следующее:

# how to put uGrid into the following codes
view = GetActiveViewOrCreate('RenderView')

# create a trivial producer to bridge between the VTK object and ParaView
tp = TrivialProducer()
tp.GetClientSideObject().SetOutput(uGrid)

dispaly = Show(tp)

Это создает прокси-сервер ParaView (TrivialProducer), который является прокси-сервером для простого источника данных VTK, называемого vtkTrivialProducer. Все, что он делает, это берет набор данных и передает его любым нижестоящим фильтрам, которые его запрашивают. (Предостережение: это работает только тогда, когда вы работаете в режиме встроенного сервера из-за GetClientSideObject(), что довольно часто).

Существует также проблема с тем, как вы определяете ячейки. Первая запись в определении ячейки должна быть количеством точек, определяющих ячейку. Поэтому измените эту строку на

cell = np.array([[3, 1, 2, 0], [3, 3, 0, 2]], dtype=np.int)
person Cory Quammen    schedule 11.02.2019
comment
Большое спасибо, Кори. Я думаю, что это шоу знаний должно быть включено в учебник Paraview. - person Huayi Wei; 12.02.2019
comment
Это неуклюжий способ сделать это, поэтому его не следует добавлять в учебник. Лучший способ — либо через Программируемый источник, либо путем расширения VTKPythonAlgorithmBase (что вы уже почти сделали, вам просто нужно было отделить класс от скрипта, сохранить его в отдельном файле, а затем загрузить как плагин). Оба подхода описаны в главе 12 руководства ParaView (paraview.org/paraview-guide). ) - person Cory Quammen; 18.02.2019
comment
спасибо за ваше подробное объяснение. Я попробую это снова. - person Huayi Wei; 19.02.2019
comment
@CoryQuammen Здравствуйте, не могли бы вы уточнить это (предостережение: это работает только тогда, когда вы работаете во встроенном режиме сервера из-за GetClientSideObject(), что довольно распространено). Означает ли это, что он не будет работать, например, с внешним сеансом Python, подключающимся через Connect (localhost). то есть только через оболочку python локального сеанса paraview? - person M.K; 27.06.2020
comment
GetClientSideObject() возвращает объект данных VTK на клиенте. Когда вы вызываете Connect, вы подключаетесь к другому серверному процессу, поэтому GetClientSideObject() не вернет ничего полезного. Вы можете использовать paraview.servermanager.Fetch(GetActiveSource()) для передачи объекта VTK для объекта, выбранного в данный момент в браузере конвейера, клиенту. Возвращаемый объект является полным объектом данных VTK. - person Cory Quammen; 01.07.2020