Yes, of course.
I adapted the PythonAlgorithmExample reader as follows:
from paraview.util.vtkAlgorithm import *
from vtkmodules.vtkCommonCore import *
import sys
import os
import numpy as np
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
import pylibwinadcp
import paraview.python_view
from vtkmodules.vtkCommonDataModel import vtkPolyData
from vtkmodules.vtkCommonCore import VTK_DOUBLE
from vtk import vtkPoints, vtkCellArray
def createModifiedCallback(anobject):
import weakref
weakref_obj = weakref.ref(anobject)
anobject = None
def _markmodified(*args, **kwars):
o = weakref_obj()
if o is not None:
o.Modified()
return _markmodified
@smproxy.reader(name="83B_Reader", label="Python-based reader for WinADCP-files",
extensions="txt", file_description="WinADCP Files")
class PythonWinADCPReader(VTKPythonAlgorithmBase):
def __init__(self):
VTKPythonAlgorithmBase.__init__(self, nInputPorts=0, nOutputPorts=1, outputType='vtkPoints')
self._filename = None
self._data = None
self._cursor = 0
self._timesteps = None
from vtkmodules.vtkCommonCore import vtkDataArraySelection
self._arrayselection = vtkDataArraySelection()
self._arrayselection.AddObserver("ModifiedEvent", createModifiedCallback(self))
def _get_raw_data(self, requested_time):
if self._data is not None:
if requested_time is not None:
print("Requested time " + str(requested_time))
return next(x for x in self._data['frames'] if x['timestamp'] == requested_time)
else:
print("Requested item at cursor, currently at " + str(self._cursor))
data = self._data['frames'][self._cursor]
return data
else:
if self._filename is None:
raise RuntimeError("No filename specified")
else:
self._data = pylibwinadcp.load(self._filename)
self._timesteps = [x['timestamp'] for x in self._data['frames']]
bin_zero = self._data['frames'][0][0]
for entry in bin_zero:
self._arrayselection.AddArray(entry.name)
return self._get_raw_data(requested_time)
def _get_timesteps(self):
self._get_raw_data(None)
return self._timesteps if self._timesteps is not None else None
def _get_update_time(self, outInfo):
executive = self.GetExecutive()
timesteps = self._get_timesteps()
if timesteps is None or len(timesteps) == 0:
return None
elif outInfo.Has(executive.UPDATE_TIME_STEP()) and len(timesteps) > 0:
utime = outInfo.Get(executive.UPDATE_TIME_STEP())
dtime = timesteps[0]
for atime in timesteps:
if atime > utime:
return dtime
else:
dtime = atime
return dtime
else:
assert(len(timesteps) > 0)
return timesteps[0]
def _get_array_selection(self):
return self._arrayselection
@smproperty.stringvector(name="FileName")
@smdomain.filelist()
@smhint.filechooser(extensions="txt", file_description="WinADCP-Files")
def SetFileName(self, name):
"""Specify filename for the file to read."""
if self._filename != name:
self._filename = name
self._timesteps = None
self.Modified()
@smproperty.doublevector(name="TimestepValues", information_only="1", si_class="vtkSITimeStepsProperty")
def GetTimestepValues(self):
return self._get_timesteps()
@smproperty.dataarrayselection(name="Features")
def GetDataArraySelection(self):
return self._get_array_selection()
def RequestInformation(self, request, inInfoVec, outInfoVec):
executive = self.GetExecutive()
outInfo = outInfoVec.GetInformationObject(0)
outInfo.Remove(executive.TIME_STEPS())
outInfo.Remove(executive.TIME_RANGE())
timesteps = self._get_timesteps()
if timesteps is not None:
for t in timesteps:
outInfo.Append(executive.TIME_STEPS(), t)
outInfo.Append(executive.TIME_RANGE(), timesteps[0])
outInfo.Append(executive.TIME_RANGE(), timesteps[-1])
return 1
def RequestData(self, request, inInfoVec, outInfoVec):
data_time = self._get_update_time(outInfoVec.GetInformationObject(0))
raw_data = self._get_raw_data(data_time)
output = vtkPolyData.GetData(outInfoVec, 0)
p = [0,0,0]
points = vtkPoints()
vertices = vtkCellArray()
id = points.InsertNextPoint(p)
vertices.InsertNextCell(1)
vertices.InsertCellPoint(id)
output.SetPoints(points)
output.SetVerts(vertices)
output.Modified()
if data_time is not None:
output.GetInformation().Set(output.DATA_TIME_STEP(), data_time)
return 1
Sorry for the cluttered code, it has sort of grown organically while trying different things to try and get it to work.
In the meantime, I wrote a python source that generates a few points, and that one had no problems with vtkPoints()
:
from paraview.util.vtkAlgorithm import *
import numpy as np
from vtk.numpy_interface import algorithms as algs
from vtk.numpy_interface import dataset_adapter as dsa
from vtkmodules.vtkCommonDataModel import vtkPolyData
from vtkmodules.vtkCommonDataModel import vtkDataSet
#import vtk
from vtk import vtkPoints, vtkIdList, VTK_POLY_LINE
@smproxy.source(name="Test Point Source",
label="Python-based test source for instantiating points")
class PythonTestPointSource(VTKPythonAlgorithmBase):
def __init__(self):
VTKPythonAlgorithmBase.__init__(self,
nInputPorts=0,
nOutputPorts=1,
outputType='vtkPolyData')
def RequestData(self, request, inInfo, outInfo):
#output = vtkPolyData.GetData(outInfo, 0)
output = dsa.WrapDataObject(vtkDataSet.GetData(outInfo))
i = np.arange(0,10,dtype=np.int32)
x = i * 1
y = i * 2
z = i * 3
coordinates = algs.make_vector(x,y,z)
points = vtkPoints()
points.SetData(dsa.numpyTovtkDataArray(coordinates, 'Points'))
output.SetPoints(points)
output.PointData.append(i, 'Index')
output.PointData.append(i, 'Scalars')
pointIds = vtkIdList()
pointIds.SetNumberOfIds(10)
for i in range(10):
pointIds.SetId(i,i)
output.Allocate(1,1)
output.InsertNextCell(VTK_POLY_LINE, pointIds)
return 1
Thanks for your help!