Как использовать numpy в программируемом фильтре в ParaView

Предположим, у меня есть ProgrammableFilter в paraview, который получает два входа: mesh1 с данными и mesh2 без. Кроме того, я знаю перестановку точек из mesh1 в mesh2. Внутри фильтра я могу получить доступ к значениям точек через

data0=inputs[0].GetPointData().GetArray('data')`

и получить часть массива, используя

subData=data0[0:6]

Например. Но как я могу добавить это subData к выводу без цикла python?

Чтобы поэкспериментировать с кодом, я создал (не такой уж и маленький) рабочий пример:

#!/usr/bin/python
from paraview.simple import *
import numpy as np
import vtk
from vtk.util.numpy_support import numpy_to_vtk

#generate an arbitrary source with data
mesh2=Sphere()
mesh2.Center=[0.0, 0.0, 0.0]
mesh2.EndPhi=360
mesh2.EndTheta=360
mesh2.PhiResolution=100
mesh2.Radius=1.0
mesh2.StartPhi=0.0
mesh2.StartTheta=0.0
mesh2.ThetaResolution=100
mesh2.UpdatePipeline()

#add the data
mesh2Vtk=servermanager.Fetch(mesh2)
nPointsSphere=mesh2Vtk.GetNumberOfPoints()
mesh2Data=paraview.vtk.vtkFloatArray()
mesh2Data.SetNumberOfValues(nPointsSphere)
mesh2Data.SetName("mesh2Data")
#TODO: use numpy here?? do this with a ProgrammableFilter ?
data=np.random.rand(nPointsSphere,1)
for k in range(nPointsSphere):
  mesh2Data.SetValue(k, data[k])
mesh2Vtk.GetPointData().AddArray(mesh2Data)

#send back to paraview server
#from https://public.kitware.com/pipermail/paraview/2011-February/020120.html
t=TrivialProducer()
filter= t.GetClientSideObject()
filter.SetOutput(mesh2Vtk)
t.UpdatePipeline()
w=CreateWriter('Sphere_withData.vtp')
w.UpdatePipeline()
Delete(w)

#create mesh1 without data
mesh1=Line()
mesh1.Point1=[0,0,0]
mesh1.Point2=[0,0,1]
mesh1.Resolution=5
mesh1.UpdatePipeline()

progFilter=ProgrammableFilter(mesh1)
progFilter.Input=[mesh1, t]
progFilter.Script="curT=inputs[1].GetPointData().GetArray('mesh2Data')"\
  "\nglobIndices=range(0,6)"\
  "\nsubT=curT[globIndices]"\
  "\nswap=vtk.vtkFloatArray()"\
  "\nswap.SetNumberOfValues(len(globIndices))"\
  "\nswap.SetName('T')"\
  "\n#TODO: how can i avoid this loop, i.e. write output.GetPointData().AddArray(converToVTK(subT))"\
  "\nfor k in range(len(globIndices)):"\
  "\n  swap.SetValue(k,subT[k])"\
  "\noutput.PointData.AddArray(swap)"
progFilter.UpdatePipeline()
w=CreateWriter('Line_withData.vtp')
w.UpdatePipeline()
Delete(w)

Я принял ответ, потому что он выглядит правильно. Следующие два скрипта даже показывают проблему: базовый скрипт 'run.py':

src1='file1.vtu'
r1=XMLUnstructuredGridReader(FileName=src1)

progFilter=ProgrammableFilter(r1)
progFilter.Input=[r1]
with open('script.py','r') as myFile:
  progFilter.Script=myFile.read()
progFilter.UpdatePipeline()
progData=progFilter.GetPointDataInformation()
print progData.GetArray('T2').GetRange()

и скрипт для программируемого фильтра:

import vtk
import vtk.numpy_interface.dataset_adapter as dsa
import numpy as np
globIndices=inputs[0].GetPointData().GetArray('T')
subT=np.ones((globIndices.shape[0],1))
subTVtk=dsa.VTKArray(subT)
output.PointData.append(subTVtk, 'T2')

С этой комбинацией я получаю сообщения об ошибках:

  • Файл "/usr/lib/python2.7/dist-packages/vtk/numpy_interface/dataset_adapter.py", строка 652, в добавлении self.VTKObject.AddArray(arr)

    TypeError: аргумент AddArray 1: для метода требуется объект VTK

  • Файл "run.py", строка 15, в

    print progData.GetArray('T2').GetRange()
    

    AttributeError: объект «NoneType» не имеет атрибута «GetRange»

Первое сообщение об ошибке, по-видимому, является причиной второго.


person A. Nau    schedule 09.09.2017    source источник
comment
У вас есть более серьезная проблема: использование paraview.simple в программируемом фильтре приведет к неопределенному поведению и не разрешено. Вы должны придерживаться чистого кода VTK и Numpy в программируемом фильтре. Программируемый фильтр будет выполняться для всех процессов, запущенных на стороне сервера.   -  person Cory Quammen    schedule 11.09.2017
comment
Извините за путаницу. Я попытался построить рабочий пример. Этот пример представляет собой скрипт Python, который создает программируемый фильтр. Внутри фильтра я не использую paraview.simple, только vtk и numpy. См. строчку progFilter.Script=..   -  person A. Nau    schedule 12.09.2017
comment
Ты прав. Извините за шум. Я добавлю ответ ниже.   -  person Cory Quammen    schedule 26.09.2017


Ответы (1)


Вот минимальный пример, который создает массив данных VTK из массива Numpy. Вы должны быть в состоянии адаптировать его для своих целей.

import numpy as np
import vtk
from vtk.numpy_interface import dataset_adapter as da

np_arr = np.ones(6)
vtk_arr = da.VTKArray(np_arr)
output.PointData.append(vtk_arr, "my data")
person Cory Quammen    schedule 26.09.2017
comment
Спасибо за подсказку. Я адаптировал его, но получаю ошибку TypeError: AddArray аргумент 1: метод требует объект VTK в файле /usr/lib/python2.7/dist-packages/vtk/numpy_interface/dataset_adapter .py в строке 652. Думаю, с моей установкой paraview что-то не так, и я пойду другим путем. - person A. Nau; 28.09.2017
comment
Если выложите свой сценарий, я могу посмотреть. - person Cory Quammen; 29.09.2017
comment
строка vtk_arr = da.VTKArray(np_arr) не нужна. Вы должны быть в состоянии просто сделать output.PointData.append(np_arr, "my data") - person Utkarsh; 27.10.2017