2017-09-09 5 views
0

Supposons que j'ai un ProgrammableFilter en paraview, qui reçoit deux entrées: mesh1 avec data et mesh2 without. En outre, je connais la permutation des points de mesh1 à mesh2. A l'intérieur du filtre, je peux accéder aux valeurs de points parComment utiliser numpy dans le filtre programmable dans ParaView

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

et d'obtenir une partie de la matrice en utilisant

subData=data0[0:6] 

par exemple. Mais comment pourrais-je ajouter ce subData à la sortie sans une boucle python?

Pour expérimenter avec le code, je créé un (pas si petit) exemple de travail:

#!/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) 

J'ai accepté la réponse, parce qu'il semble bon. Les deux scripts montrent même le problème suivant: Script de base '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() 

et le script pour le filtre programmable:

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

Avec cette combinaison, je reçois des messages d'erreur:

  • fichier "/usr/lib/python2.7/dist-packages/vtk/numpy_interface/dataset_adapter.py", ligne 652, en append self.VTKObject.AddArray (Arr)

    TypeError: L'argument AddArray 1: méthode nécessite un objet VTK

  • File "run.py", à la ligne 15, dans

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

    AttributeError: objet 'NoneType' n'a pas d'attribut 'GetRange'

Le premier message d'erreur semble être la raison de la seconde.

+0

Vous avez un plus gros problème: l'utilisation de 'paraview.simple' dans un filtre programmable entraînera un comportement indéfini et n'est pas autorisée. Vous devez utiliser le code VTK et Numpy pur dans un filtre programmable. Le filtre programmable s'exécutera sur tous les processus s'exécutant du côté serveur. –

+0

Désolé pour la confusion. J'ai essayé de construire un exemple de travail. Cet exemple est un script python, qui crée le filtre programmable. A l'intérieur du filtre, je n'utilise pas paraview.simple, juste vtk et numpy. Voir la ligne progFilter.Script = .. –

+0

Vous avez raison. Désolé pour le bruit. Je vais ajouter une réponse ci-dessous. –

Répondre

0

Voici un exemple minimal qui crée un tableau de données VTK à partir d'un tableau Numpy. Vous devriez être capable de l'adapter à vos besoins.

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") 
+0

Merci pour l'indice. Je l'ai adapté, mais j'obtiens l'erreur __TypeError: L'argument AddArray 1: method nécessite un objet VTK__ dans le fichier **/usr/lib/python2.7/dist-packages/vtk/numpy_interface/dataset_adapter.py ** à la ligne 652. Je suppose, il y a quelque chose d'étrange avec mon installation paraview et je vais aller d'autres routes. –

+0

Si vous postez votre script, je peux jeter un oeil. –

+0

la ligne 'vtk_arr = da.VTKArray (np_arr)' n'est pas nécessaire. Vous devriez pouvoir simplement 'output.PointData.append (np_arr, "mes données") ' – Utkarsh